2 Copyright (C) 2001-2010, Parrot Foundation.
7 src/interp/inter_create.c - Parrot Interpreter Creation and Destruction
11 Create or destroy a Parrot interpreter
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.
58 PARROT_WARN_UNUSED_RESULT
60 is_env_var_set(PARROT_INTERP
, ARGIN(STRING
* var
))
62 ASSERT_ARGS(is_env_var_set
)
64 char* const value
= Parrot_getenv(interp
, var
);
67 else if (*value
== '\0')
70 retval
= !STREQ(value
, "0");
76 =item C<Parrot_Interp make_interpreter(Interp *parent, INTVAL flags)>
78 Create the Parrot interpreter. Allocate memory and clear the registers.
85 PARROT_CANNOT_RETURN_NULL
88 make_interpreter(ARGIN_NULLOK(Interp
*parent
), INTVAL flags
)
90 ASSERT_ARGS(make_interpreter
)
92 Interp
* const interp
= allocate_interpreter(parent
, flags
);
93 initialize_interpreter(interp
, (void*)&stacktop
);
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:
106 initialize_interpreter
108 for overriding subsystems (e.g. GC) which require early initialization.
115 PARROT_CANNOT_RETURN_NULL
118 allocate_interpreter(ARGIN_NULLOK(Interp
*parent
), INTVAL flags
)
120 ASSERT_ARGS(allocate_interpreter
)
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 */
131 interp
->parent_interpreter
= parent
;
133 interp
->parent_interpreter
= NULL
;
135 #if PARROT_CATCH_NULL
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 */
175 =item C<Parrot_Interp initialize_interpreter(PARROT_INTERP, void *stacktop)>
177 Initialize previously allocated interpreter.
184 PARROT_CANNOT_RETURN_NULL
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
);
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
);
227 fprintf(stderr
, "PARROT_GC_DEBUG is set but the binary was compiled "
228 "with DISABLE_GC_DEBUG.\n");
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;
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 */
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
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
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
);
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.
323 Parrot_destroy(PARROT_INTERP
)
325 ASSERT_ARGS(Parrot_destroy
)
326 #ifdef ATEXIT_DESTROY
329 Parrot_really_destroy(interp
, 0);
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.
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
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
)))
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
);
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
);
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
);
459 parrot_free_vtables(interp
);
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
;
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
);
485 Parrot_gc_finalize(interp
);
487 mem_internal_free(interp
);
499 L<include/parrot/interpreter.h>, L<src/interp/interpreter.c>.
507 * c-file-style: "parrot"
509 * vim: expandtab shiftwidth=4: