2 * Copyright (C) 2001-2010, Parrot Foundation.
6 * The interpreter API handles running the operations
9 #ifndef PARROT_INTERPRETER_H_GUARD
10 #define PARROT_INTERPRETER_H_GUARD
12 /* These should be visible to embedders. */
15 /* &gen_from_enum(interpflags.pasm) */
17 PARROT_NO_FLAGS
= 0x00,
18 PARROT_BOUNDS_FLAG
= 0x04, /* We're tracking byte code bounds */
19 PARROT_PROFILE_FLAG
= 0x08, /* gathering profile information */
20 PARROT_GC_DEBUG_FLAG
= 0x10, /* debugging memory management */
22 PARROT_EXTERN_CODE_FLAG
= 0x100, /* reusing another interp's code */
23 PARROT_DESTROY_FLAG
= 0x200, /* the last interpreter shall cleanup */
25 PARROT_IS_THREAD
= 0x1000, /* interpreter is a thread */
26 PARROT_THR_COPY_INTERP
= 0x2000, /* thread start copies interp state */
27 PARROT_THR_THREAD_POOL
= 0x4000, /* type3 threads */
32 /* &gen_from_enum(interpdebug.pasm) */
34 PARROT_NO_DEBUG
= 0x00,
35 PARROT_MEM_STAT_DEBUG_FLAG
= 0x01, /* memory usage summary */
36 PARROT_BACKTRACE_DEBUG_FLAG
= 0x02, /* print bt in exception */
37 PARROT_JIT_DEBUG_FLAG
= 0x04, /* create jit stabs file */
38 PARROT_START_DEBUG_FLAG
= 0x08,
39 PARROT_THREAD_DEBUG_FLAG
= 0x10,
40 PARROT_EVAL_DEBUG_FLAG
= 0x20, /* create EVAL_n file */
41 PARROT_REG_DEBUG_FLAG
= 0x40, /* fill I,N with garbage */
42 PARROT_CTX_DESTROY_DEBUG_FLAG
= 0x80, /* ctx of a sub is gone */
43 PARROT_ALL_DEBUG_FLAGS
= 0xffff
47 /* &gen_from_enum(interptrace.pasm) */
49 PARROT_NO_TRACE
= 0x00,
50 PARROT_TRACE_OPS_FLAG
= 0x01, /* op execution trace */
51 PARROT_TRACE_FIND_METH_FLAG
= 0x02, /* find_method */
52 PARROT_TRACE_SUB_CALL_FLAG
= 0x04, /* invoke/retcc */
53 PARROT_ALL_TRACE_FLAGS
= 0xffff
57 /* &gen_from_enum(interpcores.pasm) */
59 PARROT_SLOW_CORE
, /* slow bounds/trace/profile core */
60 PARROT_FUNCTION_CORE
= PARROT_SLOW_CORE
,
61 PARROT_FAST_CORE
= 0x01, /* fast DO_OP core */
62 PARROT_EXEC_CORE
= 0x20, /* TODO Parrot_exec_run variants */
63 PARROT_GC_DEBUG_CORE
= 0x40, /* run GC before each op */
64 PARROT_DEBUGGER_CORE
= 0x80, /* used by parrot debugger */
65 PARROT_PROFILING_CORE
= 0x160 /* used by parrot debugger */
69 /* &gen_from_enum(cloneflags.pasm) */
71 PARROT_CLONE_CODE
= 0x1, /* active code segments
72 * XXX interaction with lexicals
74 PARROT_CLONE_GLOBALS
= 0x2, /* global stash */
75 PARROT_CLONE_RUNOPS
= 0x4, /* runops choice */
76 PARROT_CLONE_INTERP_FLAGS
= 0x8, /* bounds checking and
78 PARROT_CLONE_HLL
= 0x10, /* clone HLL setting */
79 PARROT_CLONE_CLASSES
= 0x20, /* clone usermade classes */
80 PARROT_CLONE_LIBRARIES
= 0x40, /* clone loaded library set */
81 /* flags that won't be initially implemented */
82 PARROT_CLONE_CC
= 0x80, /* clone current continuation --
83 * fork()-like cloning (requires
84 * cloned code segments); probably
85 * would only work if runloop_level is 1 */
87 /* combinations of flags */
88 PARROT_CLONE_DEFAULT
= 0x7f /* everything but CC */
92 struct parrot_interp_t
;
94 /* One of the most common shim arguments is the interpreter itself, so it
95 * gets its own macro. */
96 #define PARROT_INTERP /*@notnull@*/ /*@in@*/ Parrot_Interp interp
97 #define NULLOK_INTERP /*@null@*/ /*@in@*/ Parrot_Interp interp
98 #define SHIM_INTERP /*@unused@*/ /*@null@*/ Parrot_Interp interp_unused __attribute__unused__
101 #ifdef PARROT_IN_CORE
103 #define Parrot_Language Parrot_Int
104 #define Parrot_Vtable struct _vtable*
106 typedef Parrot_Interp_flag Interp_flags
;
107 typedef Parrot_Run_core_t Run_Cores
;
109 #define Interp_flags_SET(interp, flag) ((interp)->flags |= (flag))
110 #define Interp_flags_CLEAR(interp, flag) ((interp)->flags &= ~(flag))
111 #define Interp_flags_TEST(interp, flag) ((interp)->flags & (flag))
113 #define Interp_debug_SET(interp, flag) ((interp)->debug_flags |= (flag))
114 #define Interp_debug_CLEAR(interp, flag) ((interp)->debug_flags &= ~(flag))
115 #define Interp_debug_TEST(interp, flag) ((interp)->debug_flags & (flag))
117 #define Interp_trace_SET(interp, flag) Parrot_pcc_trace_flags_on(interp, interp->ctx, (flag))
118 #define Interp_trace_CLEAR(interp, flag) Parrot_pcc_trace_flags_off(interp, interp->ctx, (flag))
119 #define Interp_trace_TEST(interp, flag) Parrot_pcc_trace_flags_test(interp, interp->ctx, (flag))
121 #define Interp_core_SET(interp, core) ((interp)->run_core = (core))
122 #define Interp_core_TEST(interp, core) ((interp)->run_core == (core))
124 #include "parrot/context.h"
125 #include "parrot/parrot.h"
126 #include "parrot/warnings.h"
128 #include "parrot/op.h"
129 #include "parrot/oplib.h"
131 #include "parrot/debugger.h"
132 #include "parrot/multidispatch.h"
133 #include "parrot/call.h"
135 typedef struct warnings_t
{
136 Warnings_classes classes
;
139 /* Forward declaration for imc_info_t -- the actual struct is
140 * defined in imcc/imc.h */
144 struct _Thread_data
; /* in thread.h */
145 struct _Caches
; /* caches .h */
147 /* Get Context from interpreter */
148 #define CONTEXT(interp) Parrot_pcc_get_context_struct((interp), (interp)->ctx)
151 * Helper macros to fetch fields from context.
153 * Not considered as part of public API. Should be replaced with proper accessor
154 * functions to manipulate Context.
156 #define CURRENT_CONTEXT(interp) ((interp)->ctx)
159 typedef struct _context_mem
{
160 void **free_list
; /* array of free-lists, per size free slots */
161 int n_free_slots
; /* amount of allocated */
164 struct _handler_node_t
; /* forward def - exit.h */
166 /* The actual interpreter structure */
167 struct parrot_interp_t
{
168 PMC
*ctx
; /* current Context */
170 struct Memory_Pools
*mem_pools
; /* Pointer to this interpreter's
173 struct GC_Subsystem
*gc_sys
; /*functions and data specific
174 to current GC subsystem*/
176 PMC
*gc_registry
; /* root set of registered PMCs */
178 PMC
*class_hash
; /* Hash of classes */
179 VTABLE
**vtables
; /* array of vtable ptrs */
180 int n_vtable_max
; /* highest used type */
181 int n_vtable_alloced
; /* alloced vtable space */
183 struct _ParrotIOData
*piodata
; /* interpreter's IO system */
185 op_lib_t
*op_lib
; /* Opcode library */
186 size_t op_count
; /* The number of ops */
187 op_info_t
*op_info_table
; /* Opcode info table
188 * (name, nargs, arg types) */
190 op_func_t
*op_func_table
; /* opcode dispatch table
191 * (functions, labels, or nothing
192 * (e.g. switched core), which
193 * the interpreter is currently
196 op_func_t
*evc_func_table
; /* event check opcode dispatch */
197 op_func_t
*save_func_table
; /* for restoring op_func_table */
199 int n_libs
; /* count of libs below */
200 op_lib_t
**all_op_libs
; /* all loaded opcode libraries */
202 INTVAL flags
; /* Various interpreter flags that
203 * signal that runops should do
206 UINTVAL debug_flags
; /* debug settings */
208 struct runcore_t
*run_core
; /* type of core to run the ops */
209 struct runcore_t
**cores
; /* array of known runcores */
210 UINTVAL num_cores
; /* number of known runcores */
213 size_t resume_offset
;
215 PackFile_ByteCode
*code
; /* The code we are executing */
216 struct PackFile
*initial_pf
; /* first created PF */
218 struct _imc_info_t
*imc_info
; /* imcc data */
220 const char *output_file
; /* where to write output */
222 PDB_t
*pdb
; /* debug /trace system */
224 PMC
* dynamic_env
; /* Dynamic environment stack */
226 void *lo_var_ptr
; /* Pointer to memory on runops
229 Interp
*parent_interpreter
;
231 /* per interpreter global vars */
232 INTVAL world_inited
; /* world_init_once() is done */
234 UINTVAL hash_seed
; /* STRING hash seed */
236 PMC
*iglobals
; /* FixedPMCArray of PMCs, containing: */
237 /* 0: PMC *Parrot_base_classname_hash; hash containing name->base_type */
238 /* 1: PMC *Parrot_compreg_hash; hash containing assembler/compilers */
239 /* 2: PMC *Argv; list of argv */
240 /* 3: PMC *NCI func hash hash of NCI funcs */
241 /* 4: PMC *ParrotInterpreter that's me */
242 /* 5: PMC *Dyn_libs dynamically loaded ParrotLibrary */
243 /* 6: PMC *Config_Hash Hash of config settings */
244 /* 7: PMC *Lib_Paths LoL of search paths */
245 /* 8: PMC *PBC_Libs Hash of load_bytecode cde */
246 /* 9: PMC *Executable String PMC with name from argv[0]. */
249 PMC
*HLL_info
; /* HLL names and types */
250 PMC
*HLL_namespace
; /* cache of HLL toplevel ns */
252 PMC
*root_namespace
; /* namespace hash */
253 PMC
*scheduler
; /* concurrency scheduler */
255 MMD_Cache
*op_mmd_cache
; /* MMD cache for builtins. */
257 struct _Caches
* caches
; /* see caches.h */
259 STRING
**const_cstring_table
; /* CONST_STRING(x) items */
260 Hash
*const_cstring_hash
; /* cache of const_string items */
262 struct QUEUE
* task_queue
; /* per interpreter queue */
263 struct _handler_node_t
*exit_handler_list
;/* exit.c */
264 int sleeping
; /* used during sleep in events */
266 struct parrot_runloop_t
*current_runloop
; /* internal runloop jump point stack */
267 struct parrot_runloop_t
*runloop_jmp_free_list
; /* and free list */
269 int current_runloop_level
; /* for reentering run loop */
270 int current_runloop_id
;
272 struct _Thread_data
*thread_data
; /* thread specific items */
274 UINTVAL recursion_limit
; /* Sub call resursion limit */
276 /* during a call sequencer the caller fills these objects
277 * inside the invoke these get moved to the context structure */
278 PMC
*current_cont
; /* the return continuation PMC */
281 /* typedef struct parrot_interp_t Interp; done in parrot.h so that
282 interpreter.h's prereq headers can
287 RESUME_RESTART
= 0x01,
289 RESUME_INITIAL
= 0x04
292 /* &gen_from_enum(iglobals.pasm) */
294 IGLOBALS_CLASSNAME_HASH
,
295 IGLOBALS_COMPREG_HASH
,
300 IGLOBALS_INTERPRETER
, /* this interpreter as ParrotInterpreter PMC */
301 IGLOBALS_DYN_LIBS
, /* Hash of ParrotLibrary loaded dynamic ext */
302 IGLOBALS_CONFIG_HASH
,
303 IGLOBALS_LIB_PATHS
, /* LoL of search paths and dynamic ext */
304 IGLOBALS_PBC_LIBS
, /* Hash of load_bytecode cde */
305 IGLOBALS_EXECUTABLE
, /* How Parrot was invoked (from argv[0]) */
311 #define PCONST(i) PF_CONST(interp->code, (i))
312 #define PNCONST PF_NCONST(interp->code)
314 /* TODO - Make this a config option */
315 #ifndef PARROT_CATCH_NULL
317 # define PARROT_CATCH_NULL 0
319 # define PARROT_CATCH_NULL 1
323 /* Maybe PMC_IS_NULL(interp, pmc) ? */
324 #if PARROT_CATCH_NULL
325 PARROT_DATA PMC
*PMCNULL
; /* Holds single Null PMC */
326 PARROT_DATA STRING
*STRINGNULL
; /* a single Null STRING */
327 # define PMC_IS_NULL(pmc) ((pmc) == PMCNULL || (pmc) == NULL)
328 # define STRING_IS_NULL(s) ((s) == STRINGNULL || (s) == NULL)
330 # define PMCNULL ((PMC *)NULL)
331 # define STRINGNULL ((STRING *)NULL)
332 # define PMC_IS_NULL(pmc) ((pmc) == NULL)
333 # define STRING_IS_NULL(string) ((string) == NULL)
334 #endif /* PARROT_CATCH_NULL */
336 #define STRING_IS_EMPTY(s) ((s)->strlen == 0)
338 /* &gen_from_def(sysinfo.pasm) prefix(SYSINFO_) */
340 #define PARROT_INTSIZE 1
341 #define PARROT_FLOATSIZE 2
342 #define PARROT_POINTERSIZE 3
344 #define PARROT_OS_VERSION 5
345 #define PARROT_OS_VERSION_NUMBER 6
348 #define PARROT_INTMAX 9
349 #define PARROT_INTMIN 10
353 typedef opcode_t
*(*native_func_t
)(PARROT_INTERP
,
354 opcode_t
* cur_opcode
,
355 opcode_t
* start_code
);
357 VAR_SCOPE native_func_t run_native
;
359 typedef PMC
*(*Parrot_compiler_func_t
)(PARROT_INTERP
,
360 const char * program
);
362 /* HEADERIZER BEGIN: src/interp/inter_create.c */
363 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
366 PARROT_CANNOT_RETURN_NULL
368 Parrot_Interp
allocate_interpreter(
369 ARGIN_NULLOK(Interp
*parent
),
373 PARROT_CANNOT_RETURN_NULL
374 Parrot_Interp
initialize_interpreter(PARROT_INTERP
, ARGIN(void *stacktop
))
375 __attribute__nonnull__(1)
376 __attribute__nonnull__(2);
379 PARROT_CANNOT_RETURN_NULL
381 Parrot_Interp
make_interpreter(ARGIN_NULLOK(Interp
*parent
), INTVAL flags
);
384 void Parrot_destroy(PARROT_INTERP
)
385 __attribute__nonnull__(1);
387 void Parrot_really_destroy(PARROT_INTERP
,
388 NULLOK(int exit_code
),
390 __attribute__nonnull__(1);
392 #define ASSERT_ARGS_allocate_interpreter __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
393 #define ASSERT_ARGS_initialize_interpreter __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
394 PARROT_ASSERT_ARG(interp) \
395 , PARROT_ASSERT_ARG(stacktop))
396 #define ASSERT_ARGS_make_interpreter __attribute__unused__ int _ASSERT_ARGS_CHECK = (0)
397 #define ASSERT_ARGS_Parrot_destroy __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
398 PARROT_ASSERT_ARG(interp))
399 #define ASSERT_ARGS_Parrot_really_destroy __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
400 PARROT_ASSERT_ARG(interp))
401 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
402 /* HEADERIZER END: src/interp/inter_create.c */
404 /* HEADERIZER BEGIN: src/interp/inter_cb.c */
405 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
408 void Parrot_callback_C(
409 ARGIN(char *external_data
),
410 ARGMOD_NULLOK(PMC
*user_data
))
411 __attribute__nonnull__(1)
412 FUNC_MODIFIES(*user_data
);
415 void Parrot_callback_D(
416 ARGMOD(PMC
*user_data
),
417 ARGMOD_NULLOK(char *external_data
))
418 __attribute__nonnull__(1)
419 FUNC_MODIFIES(*user_data
)
420 FUNC_MODIFIES(*external_data
);
423 PARROT_CANNOT_RETURN_NULL
424 PARROT_WARN_UNUSED_RESULT
425 PMC
* Parrot_make_cb(PARROT_INTERP
,
427 ARGIN(PMC
* user_data
),
428 ARGIN(STRING
*cb_signature
))
429 __attribute__nonnull__(1)
430 __attribute__nonnull__(2)
431 __attribute__nonnull__(3)
432 __attribute__nonnull__(4)
433 FUNC_MODIFIES(* sub
);
436 void Parrot_run_callback(PARROT_INTERP
,
437 ARGMOD(PMC
* user_data
),
438 ARGIN(char* external_data
))
439 __attribute__nonnull__(1)
440 __attribute__nonnull__(2)
441 __attribute__nonnull__(3)
442 FUNC_MODIFIES(* user_data
);
444 #define ASSERT_ARGS_Parrot_callback_C __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
445 PARROT_ASSERT_ARG(external_data))
446 #define ASSERT_ARGS_Parrot_callback_D __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
447 PARROT_ASSERT_ARG(user_data))
448 #define ASSERT_ARGS_Parrot_make_cb __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
449 PARROT_ASSERT_ARG(interp) \
450 , PARROT_ASSERT_ARG(sub) \
451 , PARROT_ASSERT_ARG(user_data) \
452 , PARROT_ASSERT_ARG(cb_signature))
453 #define ASSERT_ARGS_Parrot_run_callback __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
454 PARROT_ASSERT_ARG(interp) \
455 , PARROT_ASSERT_ARG(user_data) \
456 , PARROT_ASSERT_ARG(external_data))
457 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
458 /* HEADERIZER END: src/interp/inter_cb.c */
460 /* HEADERIZER BEGIN: src/interp/inter_misc.c */
461 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
464 PARROT_WARN_UNUSED_RESULT
465 INTVAL
interpinfo(PARROT_INTERP
, INTVAL what
)
466 __attribute__nonnull__(1);
469 PARROT_WARN_UNUSED_RESULT
470 PARROT_CANNOT_RETURN_NULL
471 PMC
* interpinfo_p(PARROT_INTERP
, INTVAL what
)
472 __attribute__nonnull__(1);
475 PARROT_WARN_UNUSED_RESULT
476 PARROT_CANNOT_RETURN_NULL
477 STRING
* interpinfo_s(PARROT_INTERP
, INTVAL what
)
478 __attribute__nonnull__(1);
481 PARROT_CANNOT_RETURN_NULL
482 void * Parrot_compile_file(PARROT_INTERP
,
483 ARGIN(const char *fullname
),
484 ARGOUT(STRING
**error
))
485 __attribute__nonnull__(1)
486 __attribute__nonnull__(2)
487 __attribute__nonnull__(3)
488 FUNC_MODIFIES(*error
);
491 void Parrot_compreg(PARROT_INTERP
,
493 ARGIN(Parrot_compiler_func_t func
))
494 __attribute__nonnull__(1)
495 __attribute__nonnull__(2)
496 __attribute__nonnull__(3);
499 void Parrot_mark_method_writes(PARROT_INTERP
,
501 ARGIN(const char *name
))
502 __attribute__nonnull__(1)
503 __attribute__nonnull__(3);
506 void register_nci_method(PARROT_INTERP
,
509 ARGIN(const char *name
),
510 ARGIN(const char *proto
))
511 __attribute__nonnull__(1)
512 __attribute__nonnull__(3)
513 __attribute__nonnull__(4)
514 __attribute__nonnull__(5);
517 void register_raw_nci_method_in_ns(PARROT_INTERP
,
521 __attribute__nonnull__(1)
522 __attribute__nonnull__(3)
523 __attribute__nonnull__(4);
525 #define ASSERT_ARGS_interpinfo __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
526 PARROT_ASSERT_ARG(interp))
527 #define ASSERT_ARGS_interpinfo_p __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
528 PARROT_ASSERT_ARG(interp))
529 #define ASSERT_ARGS_interpinfo_s __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
530 PARROT_ASSERT_ARG(interp))
531 #define ASSERT_ARGS_Parrot_compile_file __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
532 PARROT_ASSERT_ARG(interp) \
533 , PARROT_ASSERT_ARG(fullname) \
534 , PARROT_ASSERT_ARG(error))
535 #define ASSERT_ARGS_Parrot_compreg __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
536 PARROT_ASSERT_ARG(interp) \
537 , PARROT_ASSERT_ARG(type) \
538 , PARROT_ASSERT_ARG(func))
539 #define ASSERT_ARGS_Parrot_mark_method_writes __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
540 PARROT_ASSERT_ARG(interp) \
541 , PARROT_ASSERT_ARG(name))
542 #define ASSERT_ARGS_register_nci_method __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
543 PARROT_ASSERT_ARG(interp) \
544 , PARROT_ASSERT_ARG(func) \
545 , PARROT_ASSERT_ARG(name) \
546 , PARROT_ASSERT_ARG(proto))
547 #define ASSERT_ARGS_register_raw_nci_method_in_ns __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
548 PARROT_ASSERT_ARG(interp) \
549 , PARROT_ASSERT_ARG(func) \
550 , PARROT_ASSERT_ARG(name))
551 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
552 /* HEADERIZER END: src/interp/inter_misc.c */
555 /* parrotinterpreter.pmc */
556 /* XXX Would be nice if this could live in some headerized grouping */
557 void clone_interpreter(Parrot_Interp dest
, Parrot_Interp self
, INTVAL flags
);
559 #else /* !PARROT_IN_CORE */
561 typedef void * *(*native_func_t
)(PARROT_INTERP
,
565 #endif /* PARROT_IN_CORE */
568 # define PMC_IS_NULL(pmc) Parrot_pmc_is_null(NULL, (pmc))
570 #ifndef STRING_IS_NULL
571 # define STRING_IS_NULL(s) ((s) == NULL || Parrot_str_is_null(NULL, (s))
574 #endif /* PARROT_INTERPRETER_H_GUARD */
578 * c-file-style: "parrot"
580 * vim: expandtab shiftwidth=4: