fix codetest failure - ASSERT_ARGS does not have a ; after and
[parrot.git] / src / interp / inter_create.c
blob3750e53451faab51cca5da53c377041ba760e1c3
1 /*
2 Copyright (C) 2001-2010, Parrot Foundation.
3 $Id$
5 =head1 NAME
7 src/interp/inter_create.c - Parrot Interpreter Creation and Destruction
9 =head1 DESCRIPTION
11 Create or destroy a Parrot interpreter
13 =head2 Functions
15 =over 4
17 =cut
22 #include "parrot/parrot.h"
23 #include "parrot/runcore_api.h"
24 #include "parrot/oplib/core_ops.h"
25 #include "../compilers/imcc/imc.h"
26 #include "pmc/pmc_callcontext.h"
27 #include "../gc/gc_private.h"
28 #include "inter_create.str"
30 /* HEADERIZER HFILE: include/parrot/interpreter.h */
32 /* HEADERIZER BEGIN: static */
33 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
35 PARROT_WARN_UNUSED_RESULT
36 static int is_env_var_set(PARROT_INTERP, ARGIN(STRING* var))
37 __attribute__nonnull__(1)
38 __attribute__nonnull__(2);
40 #define ASSERT_ARGS_is_env_var_set __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
41 PARROT_ASSERT_ARG(interp) \
42 , PARROT_ASSERT_ARG(var))
43 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
44 /* HEADERIZER END: static */
46 #define ATEXIT_DESTROY
50 =item C<static int is_env_var_set(PARROT_INTERP, STRING* var)>
52 Checks whether the specified environment variable is set.
54 =cut
58 PARROT_WARN_UNUSED_RESULT
59 static int
60 is_env_var_set(PARROT_INTERP, ARGIN(STRING* var))
62 ASSERT_ARGS(is_env_var_set)
63 int retval;
64 char* const value = Parrot_getenv(interp, var);
65 if (value == NULL)
66 retval = 0;
67 else if (*value == '\0')
68 retval = 0;
69 else
70 retval = !STREQ(value, "0");
71 return retval;
76 =item C<Parrot_Interp make_interpreter(Interp *parent, INTVAL flags)>
78 Create the Parrot interpreter. Allocate memory and clear the registers.
80 =cut
84 PARROT_EXPORT
85 PARROT_CANNOT_RETURN_NULL
86 PARROT_MALLOC
87 Parrot_Interp
88 make_interpreter(ARGIN_NULLOK(Interp *parent), INTVAL flags)
90 ASSERT_ARGS(make_interpreter)
91 int stacktop;
92 Interp * const interp = allocate_interpreter(parent, flags);
93 initialize_interpreter(interp, (void*)&stacktop);
94 return interp;
99 =item C<Parrot_Interp allocate_interpreter(Interp *parent, INTVAL flags)>
101 Allocate new interpreter from system memory. Everything is preallocated but not
102 initialized. Used in next cycle:
104 allocate_interpreter
105 parseflags
106 initialize_interpreter
108 for overriding subsystems (e.g. GC) which require early initialization.
110 =cut
114 PARROT_EXPORT
115 PARROT_CANNOT_RETURN_NULL
116 PARROT_MALLOC
117 Parrot_Interp
118 allocate_interpreter(ARGIN_NULLOK(Interp *parent), INTVAL flags)
120 ASSERT_ARGS(allocate_interpreter)
121 Interp *interp;
123 /* Get an empty interpreter from system memory */
124 interp = mem_internal_allocate_zeroed_typed(Interp);
126 interp->lo_var_ptr = NULL;
128 /* the last interpreter (w/o) parent has to cleanup globals
129 * so remember parent if any */
130 if (parent)
131 interp->parent_interpreter = parent;
132 else {
133 interp->parent_interpreter = NULL;
135 #if PARROT_CATCH_NULL
136 PMCNULL = NULL;
137 #endif
140 * we need a global mutex to protect the interpreter array
142 MUTEX_INIT(interpreter_array_mutex);
145 /* Must initialize flags before Parrot_gc_initialize() is called
146 * so the GC_DEBUG stuff is available. */
147 interp->flags = flags;
149 interp->ctx = PMCNULL;
150 interp->resume_flag = RESUME_INITIAL;
152 interp->recursion_limit = RECURSION_LIMIT;
154 /* PANIC will fail until this is done */
155 interp->piodata = NULL;
157 /* create exceptions list */
158 interp->current_runloop_id = 0;
159 interp->current_runloop_level = 0;
161 /* Allocate IMCC info */
162 IMCC_INFO(interp) = mem_internal_allocate_zeroed_typed(imc_info_t);
164 interp->gc_sys = mem_internal_allocate_zeroed_typed(GC_Subsystem);
165 interp->gc_sys->sys_type = parent
166 ? parent->gc_sys->sys_type
167 : PARROT_GC_DEFAULT_TYPE;
169 /* Done. Return and be done with it */
170 return interp;
175 =item C<Parrot_Interp initialize_interpreter(PARROT_INTERP, void *stacktop)>
177 Initialize previously allocated interpreter.
179 =cut
183 PARROT_EXPORT
184 PARROT_CANNOT_RETURN_NULL
185 Parrot_Interp
186 initialize_interpreter(PARROT_INTERP, ARGIN(void *stacktop))
188 ASSERT_ARGS(initialize_interpreter)
190 /* Set up the memory allocation system */
191 Parrot_gc_initialize(interp, stacktop);
192 Parrot_block_GC_mark(interp);
193 Parrot_block_GC_sweep(interp);
195 interp->ctx = PMCNULL;
196 interp->resume_flag = RESUME_INITIAL;
198 interp->recursion_limit = RECURSION_LIMIT;
200 /* PANIC will fail until this is done */
201 interp->piodata = NULL;
202 Parrot_io_init(interp);
205 * Set up the string subsystem
206 * This also generates the constant string tables
208 Parrot_str_init(interp);
210 /* Set up MMD; MMD cache for builtins. */
211 interp->op_mmd_cache = Parrot_mmd_cache_create(interp);
213 /* create caches structure */
214 init_object_cache(interp);
216 /* initialize classes - this needs mmd func table */
217 interp->HLL_info = NULL;
219 Parrot_initialize_core_vtables(interp);
220 init_world_once(interp);
222 /* context data */
223 if (is_env_var_set(interp, CONST_STRING(interp, "PARROT_GC_DEBUG"))) {
224 #if ! DISABLE_GC_DEBUG
225 Interp_flags_SET(interp, PARROT_GC_DEBUG_FLAG);
226 #else
227 fprintf(stderr, "PARROT_GC_DEBUG is set but the binary was compiled "
228 "with DISABLE_GC_DEBUG.\n");
229 #endif
232 /* Initialize interpreter's flags */
233 PARROT_WARNINGS_off(interp, PARROT_WARNINGS_ALL_FLAG);
235 /* same with errors */
236 PARROT_ERRORS_off(interp, PARROT_ERRORS_ALL_FLAG);
238 /* undefined globals are errors by default */
239 PARROT_ERRORS_on(interp, PARROT_ERRORS_GLOBALS_FLAG);
241 /* param count mismatch is an error by default */
242 PARROT_ERRORS_on(interp, PARROT_ERRORS_PARAM_COUNT_FLAG);
244 create_initial_context(interp);
246 /* clear context introspection vars */
247 Parrot_pcc_set_sub(interp, CURRENT_CONTEXT(interp), NULL);
248 Parrot_pcc_set_continuation(interp, CURRENT_CONTEXT(interp), NULL); /* TODO Use PMCNULL */
249 Parrot_pcc_set_object(interp, CURRENT_CONTEXT(interp), NULL);
251 /* initialize built-in runcores */
252 Parrot_runcore_init(interp);
254 /* Load the core op func and info tables */
255 interp->all_op_libs = NULL;
256 interp->evc_func_table = NULL;
257 interp->evc_func_table_size = 0;
258 interp->code = NULL;
260 /* create the root set registry */
261 interp->gc_registry = Parrot_pmc_new(interp, enum_class_AddrRegistry);
263 /* And a dynamic environment stack */
264 /* TODO: We should really consider removing this (TT #876) */
265 interp->dynamic_env = Parrot_pmc_new(interp, enum_class_ResizablePMCArray);
267 /* create exceptions list */
268 interp->current_runloop_id = 0;
269 interp->current_runloop_level = 0;
271 /* setup stdio PMCs */
272 Parrot_io_init(interp);
274 /* init IMCC compiler */
275 imcc_init(interp);
277 /* Done. Return and be done with it */
279 /* Okay, we've finished doing anything that might trigger GC.
280 * Actually, we could enable GC earlier, but here all setup is
281 * done
283 Parrot_unblock_GC_mark(interp);
284 Parrot_unblock_GC_sweep(interp);
286 /* all sys running, init the event and signal stuff
287 * the first or "master" interpreter is handling events and signals
289 interp->task_queue = NULL;
290 interp->thread_data = NULL;
292 Parrot_cx_init_scheduler(interp);
294 #ifdef ATEXIT_DESTROY
296 * if this is not a threaded interpreter, push the interpreter
297 * destruction.
298 * Threaded interpreters are destructed when the thread ends
300 if (!Interp_flags_TEST(interp, PARROT_IS_THREAD))
301 Parrot_on_exit(interp, Parrot_really_destroy, NULL);
302 #endif
304 return interp;
310 =item C<void Parrot_destroy(PARROT_INTERP)>
312 Does nothing if C<ATEXIT_DESTROY> is defined. Otherwise calls
313 C<Parrot_really_destroy()> with exit code 0.
315 This function is not currently used.
317 =cut
321 PARROT_EXPORT
322 void
323 Parrot_destroy(PARROT_INTERP)
325 ASSERT_ARGS(Parrot_destroy)
326 #ifdef ATEXIT_DESTROY
327 UNUSED(interp);
328 #else
329 Parrot_really_destroy(interp, 0);
330 #endif
335 =item C<void Parrot_really_destroy(PARROT_INTERP, int exit_code, void *arg)>
337 Waits for any threads to complete, then frees all allocated memory, and
338 closes any open file handles, etc.
340 Note that C<exit_code> is ignored.
342 =cut
346 void
347 Parrot_really_destroy(PARROT_INTERP, SHIM(int exit_code), SHIM(void *arg))
349 ASSERT_ARGS(Parrot_really_destroy)
350 /* wait for threads to complete if needed; terminate the event loop */
351 if (!interp->parent_interpreter) {
352 Parrot_cx_runloop_end(interp);
353 pt_join_threads(interp);
356 /* if something needs destruction (e.g. closing PIOs)
357 * we must destroy it now:
359 * Be sure that an async collector hasn't live bits set now, so
360 * trigger a finish run
362 * Need to turn off GC blocking, else things stay alive and IO
363 * handles aren't closed
365 Parrot_gc_completely_unblock(interp);
367 /* Set non buffered mode in standard out and err handles, flushing
368 * the buffers and avoiding pending output gets confused or lost in
369 * case of errors during destruction.
371 Parrot_io_setbuf(interp,
372 Parrot_io_stdhandle(interp, PIO_STDOUT_FILENO, NULL), PIOCTL_NONBUF);
373 Parrot_io_setbuf(interp,
374 Parrot_io_stdhandle(interp, PIO_STDERR_FILENO, NULL), PIOCTL_NONBUF);
376 if (Interp_trace_TEST(interp, ~0)) {
377 Parrot_io_eprintf(interp, "FileHandle objects (like stdout and stderr)"
378 "are about to be closed, so clearing trace flags.\n");
379 Interp_trace_CLEAR(interp, ~0);
382 /* Destroys all PMCs, even constants and the FileHandle objects for
383 * std{in, out, err}, so don't be verbose about GC'ing. */
384 if (interp->thread_data)
385 interp->thread_data->state |= THREAD_STATE_SUSPENDED_GC;
387 Parrot_gc_mark_and_sweep(interp, GC_finish_FLAG);
390 * that doesn't get rid of constant PMCs like these in vtable->data
391 * so if such a PMC needs destroying, we get a memory leak, like for
392 * the SharedRef PMC
393 * TODO sweep constants too or special treatment - depends on how
394 * many constant PMCs we'll create
397 /* destroy IMCC compiler */
398 imcc_destroy(interp);
400 /* Now the PIOData gets also cleared */
401 Parrot_io_finish(interp);
403 /* deinit runcores and dynamic op_libs */
404 if (!interp->parent_interpreter)
405 Parrot_runcore_destroy(interp);
408 * now all objects that need timely destruction should be finalized
409 * so terminate the event loop
411 /* if (!interp->parent_interpreter) {
412 PIO_internal_shutdown(interp);
413 Parrot_kill_event_loop(interp);
417 /* we destroy all child interpreters and the last one too,
418 * if the --leak-test commandline was given */
419 if (! (interp->parent_interpreter
420 || Interp_flags_TEST(interp, PARROT_DESTROY_FLAG)))
421 return;
423 if (interp->parent_interpreter
424 && interp->thread_data
425 && (interp->thread_data->state & THREAD_STATE_JOINED)) {
426 Parrot_gc_destroy_child_interp(interp->parent_interpreter, interp);
429 /* MMD cache */
430 Parrot_mmd_cache_destroy(interp, interp->op_mmd_cache);
432 /* copies of constant tables */
433 Parrot_destroy_constants(interp);
435 destroy_runloop_jump_points(interp);
437 /* packfile */
438 if (interp->initial_pf)
439 PackFile_destroy(interp, interp->initial_pf);
440 /* cache structure */
441 destroy_object_cache(interp);
443 if (interp->evc_func_table) {
444 mem_gc_free(interp, interp->evc_func_table);
445 interp->evc_func_table = NULL;
446 interp->evc_func_table_size = 0;
449 /* strings, encodings - only once */
450 Parrot_str_finish(interp);
452 PARROT_CORE_OPLIB_INIT(interp, 0);
454 if (!interp->parent_interpreter) {
455 if (interp->thread_data)
456 mem_internal_free(interp->thread_data);
458 /* free vtables */
459 parrot_free_vtables(interp);
461 /* Finalyze GC */
462 Parrot_gc_finalize(interp);
464 MUTEX_DESTROY(interpreter_array_mutex);
465 mem_internal_free(interp);
467 /* finally free other globals */
468 mem_internal_free(interpreter_array);
469 interpreter_array = NULL;
472 else {
473 /* don't free a thread interpreter, if it isn't joined yet */
474 if (!interp->thread_data
475 || (interp->thread_data
476 && (interp->thread_data->state & THREAD_STATE_JOINED))) {
477 if (interp->thread_data) {
478 mem_internal_free(interp->thread_data);
479 interp->thread_data = NULL;
482 parrot_free_vtables(interp);
484 /* Finalyze GC */
485 Parrot_gc_finalize(interp);
487 mem_internal_free(interp);
495 =back
497 =head1 SEE ALSO
499 L<include/parrot/interpreter.h>, L<src/interp/interpreter.c>.
501 =cut
506 * Local variables:
507 * c-file-style: "parrot"
508 * End:
509 * vim: expandtab shiftwidth=4: