2 * Copyright (C) 2001-2008, The Perl Foundation.
6 * Data Structure and Algorithms:
7 * Subroutine, coroutine, closure and continuation structures
8 * and related routines.
10 * Initial version by Melvin on on 2002/06/6
15 #ifndef PARROT_SUB_H_GUARD
16 #define PARROT_SUB_H_GUARD
18 #include "parrot/parrot.h"
24 /* runtime usage flags */
25 SUB_FLAG_CORO_FF
= PObj_private0_FLAG
,
26 SUB_FLAG_C_HANDLER
= PObj_private0_FLAG
, /* C exceptions only */
27 SUB_FLAG_TAILCALL
= PObj_private2_FLAG
,
28 SUB_FLAG_GENERATOR
= PObj_private3_FLAG
, /* unused old python pmcs */
30 /* compile/loadtime usage flags */
32 SUB_FLAG_IS_OUTER
= PObj_private1_FLAG
,
33 SUB_FLAG_PF_ANON
= PObj_private3_FLAG
,
34 SUB_FLAG_PF_MAIN
= PObj_private4_FLAG
,
35 SUB_FLAG_PF_LOAD
= PObj_private5_FLAG
,
36 SUB_FLAG_PF_IMMEDIATE
= PObj_private6_FLAG
,
37 SUB_FLAG_PF_POSTCOMP
= PObj_private7_FLAG
,
39 /* [temporary expedient. -- rgr, 13-Jul-08.] */
40 SUB_FLAG_NEWCLOSURE
= SUB_FLAG_PF_IMMEDIATE
,
42 SUB_FLAG_PF_MASK
= 0xfa /* anon ... postcomp, is_outer*/
45 #define SUB_FLAG_get_FLAGS(o) (PObj_get_FLAGS(o))
46 #define SUB_FLAG_flag_TEST(flag, o) (SUB_FLAG_get_FLAGS(o) & SUB_FLAG_ ## flag)
47 #define SUB_FLAG_flag_SET(flag, o) (SUB_FLAG_get_FLAGS(o) |= SUB_FLAG_ ## flag)
48 #define SUB_FLAG_flag_CLEAR(flag, o) (SUB_FLAG_get_FLAGS(o) &= ~(UINTVAL)(SUB_FLAG_ ## flag))
50 #define SUB_FLAG_flags_SETTO(o, f) SUB_FLAG_get_FLAGS(o) = (f)
51 #define SUB_FLAG_flags_CLEARALL(o) SUB_FLAG_flags_SETTO((o), 0)
53 #define SUB_FLAG_TAILCALL_TEST(o) SUB_FLAG_flag_TEST(TAILCALL, (o))
54 #define SUB_FLAG_TAILCALL_ISSET(o) SUB_FLAG_flag_TEST(TAILCALL, (o))
55 #define SUB_FLAG_TAILCALL_NOTSET(o) (!SUB_FLAG_flag_TEST(TAILCALL, (o)))
56 #define SUB_FLAG_TAILCALL_SET(o) SUB_FLAG_flag_SET(TAILCALL, (o))
57 #define SUB_FLAG_TAILCALL_CLEAR(o) SUB_FLAG_flag_CLEAR(TAILCALL, (o))
59 #define SUB_FLAG(n) ((UINTVAL)1 << (n))
61 SUB_COMP_FLAG_BIT_0
= SUB_FLAG(0),
62 SUB_COMP_FLAG_BIT_1
= SUB_FLAG(1),
63 SUB_COMP_FLAG_BIT_2
= SUB_FLAG(2),
64 SUB_COMP_FLAG_METHOD
= SUB_COMP_FLAG_BIT_2
,
65 SUB_COMP_FLAG_BIT_3
= SUB_FLAG(3),
66 SUB_COMP_FLAG_BIT_4
= SUB_FLAG(4),
67 SUB_COMP_FLAG_BIT_5
= SUB_FLAG(5),
68 SUB_COMP_FLAG_BIT_6
= SUB_FLAG(6),
69 SUB_COMP_FLAG_BIT_7
= SUB_FLAG(7),
70 SUB_COMP_FLAG_BIT_8
= SUB_FLAG(8),
71 SUB_COMP_FLAG_BIT_9
= SUB_FLAG(9),
72 SUB_COMP_FLAG_BIT_10
= SUB_FLAG(10),
73 SUB_COMP_FLAG_PF_INIT
= SUB_COMP_FLAG_BIT_10
,
74 SUB_COMP_FLAG_BIT_11
= SUB_FLAG(11),
75 SUB_COMP_FLAG_BIT_12
= SUB_FLAG(12),
76 SUB_COMP_FLAG_BIT_13
= SUB_FLAG(13),
77 SUB_COMP_FLAG_BIT_14
= SUB_FLAG(14),
78 SUB_COMP_FLAG_BIT_15
= SUB_FLAG(15),
79 SUB_COMP_FLAG_BIT_16
= SUB_FLAG(16),
80 SUB_COMP_FLAG_BIT_17
= SUB_FLAG(17),
81 SUB_COMP_FLAG_BIT_18
= SUB_FLAG(18),
82 SUB_COMP_FLAG_BIT_19
= SUB_FLAG(19),
83 SUB_COMP_FLAG_BIT_20
= SUB_FLAG(20),
84 SUB_COMP_FLAG_BIT_21
= SUB_FLAG(21),
85 SUB_COMP_FLAG_BIT_22
= SUB_FLAG(22),
86 SUB_COMP_FLAG_BIT_23
= SUB_FLAG(23),
87 SUB_COMP_FLAG_BIT_24
= SUB_FLAG(24),
88 SUB_COMP_FLAG_BIT_25
= SUB_FLAG(25),
89 SUB_COMP_FLAG_BIT_26
= SUB_FLAG(26),
90 SUB_COMP_FLAG_BIT_27
= SUB_FLAG(27),
91 SUB_COMP_FLAG_BIT_28
= SUB_FLAG(28),
92 SUB_COMP_FLAG_BIT_29
= SUB_FLAG(29),
93 SUB_COMP_FLAG_BIT_30
= SUB_FLAG(30),
94 SUB_COMP_FLAG_MASK
= 0x00000404
95 } sub_comp_flags_enum
;
98 #define Sub_comp_get_FLAGS(o) ((PMC_sub(o))->comp_flags)
99 #define Sub_comp_flag_TEST(flag, o) (Sub_comp_get_FLAGS(o) & SUB_COMP_FLAG_ ## flag)
100 #define Sub_comp_flag_SET(flag, o) (Sub_comp_get_FLAGS(o) |= SUB_COMP_FLAG_ ## flag)
101 #define Sub_comp_flag_CLEAR(flag, o) (Sub_comp_get_FLAGS(o) &= ~(UINTVAL)(SUB_COMP_FLAG_ ## flag))
103 #define Sub_comp_flags_SETTO(o, f) Sub_comp_get_FLAGS(o) = (f)
104 #define Sub_comp_flags_CLEARALL(o) Sub_comp_flags_SETTO((o), 0)
106 #define Sub_comp_INIT_TEST(o) Sub_comp_flag_TEST(PF_INIT, o)
107 #define Sub_comp_INIT_SET(o) Sub_comp_flag_SET(PF_INIT, o)
108 #define Sub_comp_INIT_CLEAR(o) Sub_comp_flag_CLEAR(PF_INIT, o)
111 * a flag to signal a Sub that a new RetContinuation should be created
114 #define NEED_CONTINUATION ((PMC *)1)
117 * maximum sub recursion depth
120 #define RECURSION_LIMIT 1000
124 * Counts and flags describing the arguments.
126 typedef struct Parrot_sub_arginfo
{
127 Parrot_UInt2 pos_required
;
128 Parrot_UInt2 pos_optional
;
129 Parrot_UInt2 named_required
;
130 Parrot_UInt2 named_optional
;
131 Parrot_UInt1 pos_slurpy
;
132 Parrot_UInt1 named_slurpy
;
133 } Parrot_sub_arginfo
;
137 * Sub and Closure share a Parrot_sub structure.
138 * Closures have additionally an 'outer_ctx'
140 typedef struct Parrot_sub
{
141 struct PackFile_ByteCode
*seg
; /* bytecode segment */
142 size_t start_offs
; /* sub entry in ops from seg->base.data */
145 INTVAL HLL_id
; /* see src/hll.c XXX or per segment? */
146 PMC
*namespace_name
; /* where this Sub is in - this is either
147 * a String or a [Key] and describes
148 * the relative path in the NameSpace
150 PMC
*namespace_stash
; /* the actual hash, HLL::namespace */
151 STRING
*name
; /* name of the sub */
152 STRING
*lexid
; /* The lexical ID of the sub. */
153 INTVAL vtable_index
; /* index in Parrot_vtable_slot_names */
154 PMC
*multi_signature
; /* list of types for MMD */
155 INTVAL n_regs_used
[4]; /* INSP in PBC */
157 PMC
*lex_info
; /* LexInfo PMC */
158 PMC
*outer_sub
; /* :outer for closures */
159 PMC
*eval_pmc
; /* eval container / NULL */
160 parrot_context_t
*ctx
; /* the context this sub is in */
161 UINTVAL comp_flags
; /* compile time and additional flags */
162 Parrot_sub_arginfo
*arg_info
;/* Argument counts and flags. */
165 struct Parrot_Context
*outer_ctx
; /* outer context, if a closure */
168 #define PMC_sub(pmc) ((Parrot_sub *)PMC_struct_val(pmc))
170 /* the first entries must match Parrot_sub, so we can cast
171 * these two to the other type
173 typedef struct Parrot_coro
{
174 struct PackFile_ByteCode
*seg
; /* bytecode segment */
175 size_t start_offs
; /* sub entry in ops from seg->base.data */
178 INTVAL HLL_id
; /* see src/hll.c XXX or per segment? */
179 PMC
*_namespace
; /* where this Sub is in - this is either
180 * a String or a [Key] and describes
181 * the relative path in the NameSpace
183 PMC
*namespace_stash
; /* the actual hash, HLL::namespace */
184 STRING
*name
; /* name of the sub */
185 STRING
*lexid
; /* The lexical ID of the sub. */
186 INTVAL vtable_index
; /* index in Parrot_vtable_slot_names */
187 PMC
*multi_signature
; /* list of types for MMD */
188 INTVAL n_regs_used
[4]; /* INSP in PBC */
190 PMC
*lex_info
; /* LexInfo PMC */
191 PMC
*outer_sub
; /* :outer for closures */
192 PMC
*eval_pmc
; /* eval container / NULL */
193 struct Parrot_Context
*ctx
; /* coroutine context */
194 UINTVAL comp_flags
; /* compile time and additional flags */
195 Parrot_sub_arginfo arg_info
; /* Argument counts and flags. */
199 struct PackFile_ByteCode
*caller_seg
; /* bytecode segment */
200 opcode_t
*address
; /* next address to run - toggled each time */
201 struct Stack_Chunk
*dynamic_state
; /* next dynamic state */
204 #define PMC_coro(pmc) ((Parrot_coro *)PMC_struct_val(pmc))
206 typedef struct Parrot_cont
{
207 /* continuation destination */
208 struct PackFile_ByteCode
*seg
; /* bytecode segment */
209 opcode_t
*address
; /* start of bytecode, addr to continue */
210 struct Parrot_Context
*to_ctx
; /* pointer to dest context */
211 struct Stack_Chunk
*dynamic_state
; /* dest dynamic state */
212 /* a Continuation keeps the from_ctx alive */
213 struct Parrot_Context
*from_ctx
; /* sub, this cont is returning from */
214 opcode_t
*current_results
; /* ptr into code with get_results opcode
215 full continuation only */
216 int runloop_id
; /* id of the creating runloop. */
217 int invoked
; /* flag when a handler has been invoked. */
220 #define PMC_cont(pmc) ((Parrot_cont *)PMC_struct_val(pmc))
222 typedef struct Parrot_Context_info
{
230 } Parrot_Context_info
;
232 /* HEADERIZER BEGIN: src/sub.c */
233 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
237 PARROT_CANNOT_RETURN_NULL
238 PMC
* new_ret_continuation_pmc(PARROT_INTERP
,
239 ARGIN_NULLOK(opcode_t
*address
))
240 __attribute__nonnull__(1);
243 int Parrot_Context_get_info(PARROT_INTERP
,
244 ARGIN(const parrot_context_t
*ctx
),
245 ARGOUT(Parrot_Context_info
*info
))
246 __attribute__nonnull__(1)
247 __attribute__nonnull__(2)
248 __attribute__nonnull__(3)
249 FUNC_MODIFIES(*info
);
252 PARROT_CAN_RETURN_NULL
253 PARROT_WARN_UNUSED_RESULT
254 STRING
* Parrot_Context_infostr(PARROT_INTERP
,
255 ARGIN(const parrot_context_t
*ctx
))
256 __attribute__nonnull__(1)
257 __attribute__nonnull__(2);
260 PARROT_CAN_RETURN_NULL
261 PARROT_WARN_UNUSED_RESULT
262 STRING
* Parrot_full_sub_name(PARROT_INTERP
, ARGIN_NULLOK(PMC
* sub
))
263 __attribute__nonnull__(1);
266 PARROT_CANNOT_RETURN_NULL
267 PARROT_WARN_UNUSED_RESULT
268 PMC
* parrot_new_closure(PARROT_INTERP
, ARGIN(PMC
*sub_pmc
))
269 __attribute__nonnull__(1)
270 __attribute__nonnull__(2);
272 void invalidate_retc_context(PARROT_INTERP
, ARGMOD(PMC
*cont
))
273 __attribute__nonnull__(1)
274 __attribute__nonnull__(2)
275 FUNC_MODIFIES(*cont
);
277 void mark_context(PARROT_INTERP
, ARGMOD(parrot_context_t
* ctx
))
278 __attribute__nonnull__(1)
279 __attribute__nonnull__(2)
280 FUNC_MODIFIES(* ctx
);
283 PARROT_CANNOT_RETURN_NULL
284 Parrot_sub
* new_closure(PARROT_INTERP
)
285 __attribute__nonnull__(1);
288 PARROT_CANNOT_RETURN_NULL
289 Parrot_cont
* new_continuation(PARROT_INTERP
,
290 ARGIN_NULLOK(const Parrot_cont
*to
))
291 __attribute__nonnull__(1);
294 PARROT_CANNOT_RETURN_NULL
295 Parrot_coro
* new_coroutine(PARROT_INTERP
)
296 __attribute__nonnull__(1);
299 PARROT_CANNOT_RETURN_NULL
300 Parrot_cont
* new_ret_continuation(PARROT_INTERP
)
301 __attribute__nonnull__(1);
304 PARROT_CANNOT_RETURN_NULL
305 Parrot_sub
* new_sub(PARROT_INTERP
)
306 __attribute__nonnull__(1);
308 void Parrot_continuation_check(PARROT_INTERP
,
310 ARGIN(Parrot_cont
*cc
))
311 __attribute__nonnull__(1)
312 __attribute__nonnull__(2)
313 __attribute__nonnull__(3);
315 void Parrot_continuation_rewind_environment(PARROT_INTERP
,
317 ARGIN(Parrot_cont
*cc
))
318 __attribute__nonnull__(1)
319 __attribute__nonnull__(2)
320 __attribute__nonnull__(3);
322 PARROT_CAN_RETURN_NULL
323 PARROT_WARN_UNUSED_RESULT
324 PMC
* Parrot_find_pad(PARROT_INTERP
,
325 ARGIN(STRING
*lex_name
),
326 ARGIN(const parrot_context_t
*ctx
))
327 __attribute__nonnull__(1)
328 __attribute__nonnull__(2)
329 __attribute__nonnull__(3);
331 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
332 /* HEADERIZER END: src/sub.c */
334 #endif /* PARROT_SUB_H_GUARD */
338 * c-file-style: "parrot"
340 * vim: expandtab shiftwidth=4: