2 Copyright (C) 2001-2008, The Perl Foundation.
7 src/inter_create.c - Parrot Interpreter Creation and Destruction
11 Create or destroy a Parrot interpreter
22 #include "parrot/parrot.h"
23 #include "parrot/oplib/core_ops.h"
24 #include "../compilers/imcc/imc.h"
25 #include "inter_create.str"
27 /* HEADERIZER HFILE: include/parrot/interpreter.h */
29 /* HEADERIZER BEGIN: static */
30 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
32 PARROT_WARN_UNUSED_RESULT
33 static int is_env_var_set(ARGIN(const char* var
))
34 __attribute__nonnull__(1);
36 static void setup_default_compreg(PARROT_INTERP
)
37 __attribute__nonnull__(1);
39 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
40 /* HEADERIZER END: static */
43 extern int Parrot_exec_run
;
50 #define ATEXIT_DESTROY
54 =item C<static int is_env_var_set>
56 Checks whether the specified environment variable is set.
62 PARROT_WARN_UNUSED_RESULT
64 is_env_var_set(ARGIN(const char* var
))
67 char* const value
= Parrot_getenv(var
, &free_it
);
70 else if (*value
== '\0')
73 retval
= !STREQ(value
, "0");
81 =item C<static void setup_default_compreg>
83 Setup default compiler for PASM.
90 setup_default_compreg(PARROT_INTERP
)
92 STRING
* const pasm1
= CONST_STRING(interp
, "PASM1");
94 /* register the nci compiler object */
95 Parrot_compreg(interp
, pasm1
, (Parrot_compiler_func_t
)PDB_compile
);
100 =item C<Parrot_Interp make_interpreter>
102 Create the Parrot interpreter. Allocate memory and clear the registers.
109 PARROT_CANNOT_RETURN_NULL
111 make_interpreter(ARGIN_NULLOK(Interp
*parent
), INTVAL flags
)
115 /* Get an empty interpreter from system memory */
121 interp
= mem_allocate_zeroed_typed(Interp
);
123 interp
->lo_var_ptr
= NULL
;
125 /* the last interpreter (w/o) parent has to cleanup globals
126 * so remember parent if any */
128 interp
->parent_interpreter
= parent
;
130 interp
->parent_interpreter
= NULL
;
133 * we need a global mutex to protect the interpreter array
135 MUTEX_INIT(interpreter_array_mutex
);
138 create_initial_context(interp
);
139 interp
->resume_flag
= RESUME_INITIAL
;
141 /* main is called as a Sub too - this will get depth 0 then */
142 CONTEXT(interp
)->recursion_depth
= (UINTVAL
)-1;
143 interp
->recursion_limit
= RECURSION_LIMIT
;
145 /* Must initialize flags here so the GC_DEBUG stuff is available before
146 * mem_setup_allocator() is called. */
147 interp
->flags
= flags
;
149 /* PANIC will fail until this is done */
150 interp
->piodata
= NULL
;
153 if (is_env_var_set("PARROT_GC_DEBUG")) {
154 #if ! DISABLE_GC_DEBUG
155 Interp_flags_SET(interp
, PARROT_GC_DEBUG_FLAG
);
157 fprintf(stderr
, "PARROT_GC_DEBUG is set but the binary was compiled "
158 "with DISABLE_GC_DEBUG.\n");
162 /* Set up the memory allocation system */
163 mem_setup_allocator(interp
);
164 Parrot_block_GC_mark(interp
);
165 Parrot_block_GC_sweep(interp
);
168 * Set up the string subsystem
169 * This also generates the constant string tables
173 /* Set up the MMD struct */
174 interp
->binop_mmd_funcs
= NULL
;
176 /* Go and init the MMD tables */
177 mmd_add_function(interp
, MMD_USER_FIRST
- 1, (funcptr_t
)NULL
);
179 /* create caches structure */
180 init_object_cache(interp
);
182 /* initialize classes - this needs mmd func table */
183 interp
->HLL_info
= NULL
;
184 init_world_once(interp
);
187 /* Initialize interpreter's flags */
188 PARROT_WARNINGS_off(interp
, PARROT_WARNINGS_ALL_FLAG
);
190 /* same with errors */
191 PARROT_ERRORS_off(interp
, PARROT_ERRORS_ALL_FLAG
);
193 /* undefined globals are errors by default */
194 PARROT_ERRORS_on(interp
, PARROT_ERRORS_GLOBALS_FLAG
);
196 /* param count mismatch is an error by default */
197 PARROT_ERRORS_on(interp
, PARROT_ERRORS_PARAM_COUNT_FLAG
);
200 /* TODO not yet - too many test failures */
201 PARROT_ERRORS_on(interp
, PARROT_ERRORS_RESULT_COUNT_FLAG
);
204 /* allocate stack chunk cache */
205 stack_system_init(interp
);
207 /* And a dynamic environment stack */
208 interp
->dynamic_env
= new_stack(interp
, "DynamicEnv");
210 /* clear context introspection vars */
211 CONTEXT(interp
)->current_sub
= NULL
;
212 CONTEXT(interp
)->current_cont
= NULL
;
213 CONTEXT(interp
)->current_object
= NULL
;
215 /* Load the core op func and info tables */
216 interp
->op_lib
= PARROT_CORE_OPLIB_INIT(1);
217 interp
->op_count
= interp
->op_lib
->op_count
;
218 interp
->op_func_table
= interp
->op_lib
->op_func_table
;
219 interp
->op_info_table
= interp
->op_lib
->op_info_table
;
220 interp
->all_op_libs
= NULL
;
221 interp
->evc_func_table
= NULL
;
222 interp
->save_func_table
= NULL
;
224 interp
->profile
= NULL
;
226 /* create the root set registry */
227 interp
->DOD_registry
= pmc_new(interp
, enum_class_AddrRegistry
);
229 /* create exceptions list */
230 interp
->current_runloop_id
= 0;
231 interp
->current_runloop_level
= 0;
233 /* register assembler/compilers */
234 setup_default_compreg(interp
);
236 /* setup stdio PMCs */
239 /* init IMCC compiler */
242 /* Done. Return and be done with it */
244 /* Okay, we've finished doing anything that might trigger GC.
245 * Actually, we could enable DOD/GC earlier, but here all setup is
248 Parrot_unblock_GC_mark(interp
);
249 Parrot_unblock_GC_sweep(interp
);
251 /* all sys running, init the event and signal stuff
252 * the first or "master" interpreter is handling events and signals
254 interp
->task_queue
= NULL
;
255 interp
->thread_data
= NULL
;
257 Parrot_cx_init_scheduler(interp
);
259 #ifdef ATEXIT_DESTROY
261 * if this is not a threaded interpreter, push the interpreter
263 * Threaded interpreters are destructed when the thread ends
265 if (!Interp_flags_TEST(interp
, PARROT_IS_THREAD
))
266 Parrot_on_exit(interp
, Parrot_really_destroy
, NULL
);
274 =item C<void Parrot_destroy>
276 Does nothing if C<ATEXIT_DESTROY> is defined. Otherwise calls
277 C<Parrot_really_destroy()> with exit code 0.
279 This function is not currently used.
287 Parrot_destroy(PARROT_INTERP
)
289 #ifdef ATEXIT_DESTROY
292 Parrot_really_destroy(interp
, 0);
298 =item C<void Parrot_really_destroy>
300 Waits for any threads to complete, then frees all allocated memory, and
301 closes any open file handles, etc.
303 Note that C<exit_code> is ignored.
310 Parrot_really_destroy(PARROT_INTERP
, SHIM(int exit_code
), SHIM(void *arg
))
314 * wait for threads to complete if needed; terminate the event loop
316 if (!interp
->parent_interpreter
) {
317 Parrot_cx_runloop_end(interp
);
318 pt_join_threads(interp
);
321 /* if something needs destruction (e.g. closing PIOs)
322 * we must destroy it now:
324 * Be sure that an async collector hasn't live bits set now, so
325 * trigger a finish run
327 * Need to turn off DOD blocking, else things stay alive and IO
328 * handles aren't closed
330 interp
->arena_base
->DOD_block_level
=
331 interp
->arena_base
->GC_block_level
= 0;
333 if (Interp_trace_TEST(interp
, ~0)) {
334 PIO_eprintf(interp
, "ParrotIO objects (like stdout and stderr)"
335 "are about to be closed, so clearing trace flags.\n");
336 Interp_trace_CLEAR(interp
, ~0);
339 /* Destroys all PMCs, even constants and the ParrotIO objects for
340 * std{in, out, err}, so don't be verbose about DOD'ing. */
341 if (interp
->thread_data
)
342 interp
->thread_data
->state
|= THREAD_STATE_SUSPENDED_GC
;
344 Parrot_do_dod_run(interp
, GC_finish_FLAG
);
347 if (interp
->thread_data
&& interp
->thread_data
->stm_log
&&
348 !interp
->parent_interpreter
&&
349 Interp_debug_TEST(interp
, PARROT_THREAD_DEBUG_FLAG
))
350 Parrot_STM_dump_profile(interp
);
354 * that doesn't get rid of constant PMCs like these in vtable->data
355 * so if such a PMC needs destroying, we get a memory leak, like for
357 * TODO sweep constants too or special treatment - depends on how
358 * many constant PMCs we'll create
361 /* destroy IMCC compiler */
362 imcc_destroy(interp
);
364 /* Now the PIOData gets also cleared */
368 * now all objects that need timely destruction should be finalized
369 * so terminate the event loop
371 if (!interp
->parent_interpreter
) {
372 PIO_internal_shutdown(interp
);
373 /* Parrot_kill_event_loop(interp); */
376 /* we destroy all child interpreters and the last one too,
377 * if the --leak-test commandline was given
379 if (! (interp
->parent_interpreter
||
380 Interp_flags_TEST(interp
, PARROT_DESTROY_FLAG
)))
383 if (interp
->thread_data
&& interp
->thread_data
->stm_log
) {
384 while (Parrot_STM_transaction_depth(interp
) > 0) {
386 fprintf(stderr
, "interpreter %p had pending transaction on exit\n",
388 Parrot_STM_abort(interp
);
391 if (interp
->parent_interpreter
392 && interp
->thread_data
->state
& THREAD_STATE_JOINED
)
393 Parrot_STM_merge_profile(interp
->parent_interpreter
,
396 Parrot_STM_destroy(interp
);
399 if (interp
->parent_interpreter
&&
400 interp
->thread_data
&&
401 (interp
->thread_data
->state
& THREAD_STATE_JOINED
)) {
402 Parrot_merge_header_pools(interp
->parent_interpreter
, interp
);
403 Parrot_merge_memory_pools(interp
->parent_interpreter
, interp
);
406 if (interp
->arena_base
->finalize_gc_system
)
407 interp
->arena_base
->finalize_gc_system(interp
);
409 /* copies of constant tables */
410 Parrot_destroy_constants(interp
);
412 /* buffer headers, PMCs */
413 Parrot_destroy_header_pools(interp
);
415 /* memory pools in resources */
416 Parrot_destroy_memory_pools(interp
);
418 /* mem subsystem is dead now */
419 mem_sys_free(interp
->arena_base
);
420 interp
->arena_base
= NULL
;
422 /* cache structure */
423 destroy_object_cache(interp
);
426 if (interp
->initial_pf
)
427 PackFile_destroy(interp
, interp
->initial_pf
);
429 if (interp
->profile
) {
430 mem_sys_free(interp
->profile
->data
);
431 interp
->profile
->data
= NULL
;
432 mem_sys_free(interp
->profile
);
433 interp
->profile
= NULL
;
437 (void) PARROT_CORE_OPLIB_INIT(0);
439 stack_destroy(interp
->dynamic_env
);
441 destroy_context(interp
);
442 destroy_runloop_jump_points(interp
);
444 if (interp
->evc_func_table
) {
445 mem_sys_free(interp
->evc_func_table
);
446 interp
->evc_func_table
= NULL
;
449 /* strings, charsets, encodings - only once */
450 string_deinit(interp
);
452 if (!interp
->parent_interpreter
) {
453 if (interp
->thread_data
)
454 mem_sys_free(interp
->thread_data
);
457 parrot_free_vtables(interp
);
460 MUTEX_DESTROY(interpreter_array_mutex
);
461 mem_sys_free(interp
);
463 * finally free other globals
465 mem_sys_free(interpreter_array
);
466 interpreter_array
= NULL
;
470 /* don't free a thread interpreter, if it isn't joined yet */
471 if (!interp
->thread_data
|| (
472 interp
->thread_data
&&
473 (interp
->thread_data
->state
& THREAD_STATE_JOINED
))) {
474 if (interp
->thread_data
) {
475 mem_sys_free(interp
->thread_data
);
476 interp
->thread_data
= NULL
;
478 mem_sys_free(interp
);
489 F<include/parrot/interpreter.h>, F<src/interpreter.c>.
497 * c-file-style: "parrot"
499 * vim: expandtab shiftwidth=4: