2 Copyright (C) 2001-2008, The Perl Foundation.
7 src/pmc/coroutine.pmc - Co-Routine PMC
11 C<Coroutine> extends C<Continuation> to provide a subroutine that can
12 stop in the middle, and start back up later at the point at which it
13 stopped. See the L<Glossary|docs/glossary.pod> for more information.
19 =item private0 call flip flop
21 =item private3 restore current sub after "flop". Used by generators.
33 #include "parrot/parrot.h"
34 #include "parrot/oplib/ops.h"
37 print_sub_name(PARROT_INTERP, PMC *sub)
39 Parrot_coro * const co = PMC_coro(sub);
40 Interp * const tracer = interp->debugger ? interp->debugger : interp;
42 PIO_eprintf(tracer, "# %s coro '%Ss'",
43 !(PObj_get_FLAGS(sub) & SUB_FLAG_CORO_FF) ?
44 "Calling" : "yielding from",
45 Parrot_full_sub_name(interp, sub));
47 if (co->ctx && (PObj_get_FLAGS(sub) & SUB_FLAG_CORO_FF)) {
48 PIO_eprintf(tracer, " to '%Ss'",
49 Parrot_full_sub_name(interp,
50 co->ctx->caller_ctx->current_sub));
53 PIO_eprintf(tracer, "\n# ");
54 print_pbc_location(interp);
57 pmclass Coroutine extends Sub need_ext {
63 Initializes the co-routine.
74 PMC_struct_val(SELF) = new_coroutine(INTERP);
75 PMC_pmc_val(SELF) = PMCNULL;
76 PObj_custom_mark_destroy_SETALL(SELF);
81 =item C<void destroy()>
83 Destroys the coroutine.
89 VTABLE void destroy() {
90 Parrot_coro * const sub = PMC_coro(SELF);
93 Parrot_free_context(interp, sub->ctx, 0);
99 Parrot_coro * const sub = mem_allocate_typed(Parrot_coro);
100 PMC * const ret = pmc_new_noinit(INTERP, SELF->vtable->base_type);
102 PObj_custom_mark_destroy_SETALL(ret);
104 PMC_struct_val(ret) = sub;
105 PMC_pmc_val(ret) = PMCNULL;
107 memcpy(sub, PMC_sub(SELF), sizeof (Parrot_coro));
109 sub->name = string_copy(INTERP, sub->name);
116 =item C<opcode_t *invoke(void *next)>
124 VTABLE opcode_t *invoke(void *next) {
125 PackFile_ByteCode *wanted_seg;
126 Parrot_coro * const co = PMC_coro(SELF);
127 opcode_t * dest = co->address;
129 if (Interp_trace_TEST(INTERP, PARROT_TRACE_SUB_CALL_FLAG))
130 print_sub_name(INTERP, SELF);
133 parrot_context_t *caller_ctx;
134 parrot_context_t *ctx;
137 /* RT#46699 factor out common code with Sub.invoke and inherit it */
138 ccont = INTERP->current_cont;
140 if (ccont == NEED_CONTINUATION)
141 ccont = (PMC *)new_ret_continuation_pmc(interp,
144 if (PObj_get_FLAGS(ccont) & SUB_FLAG_TAILCALL)
145 real_exception(INTERP, NULL, E_Exception,
146 "tail call to coro not allowed");
148 /* first time set current sub, cont, object */
149 caller_ctx = CONTEXT(interp);
150 ctx = Parrot_alloc_context(INTERP, co->n_regs_used);
153 co->dynamic_state = interp->dynamic_env;
155 ctx->caller_ctx = caller_ctx;
156 PMC_cont(ccont)->from_ctx = ctx;
157 ctx->current_sub = SELF;
158 ctx->current_HLL = co->HLL_id;
159 ctx->current_namespace = co->namespace_stash;
160 ctx->current_cont = ccont;
161 ctx->current_object = NULL;
162 INTERP->current_object = NULL;
163 INTERP->current_cont = NULL;
165 /* create pad if needed */
166 if (!PMC_IS_NULL(co->lex_info)) {
167 ctx->lex_pad = pmc_new_init(INTERP,
168 Parrot_get_ctx_HLL_type(interp, enum_class_LexPad),
170 VTABLE_set_pointer(INTERP, ctx->lex_pad, ctx);
173 PObj_get_FLAGS(SELF) |= SUB_FLAG_CORO_FF;
174 wanted_seg = co->seg;
175 co->caller_seg = INTERP->code;
176 co->address = co->seg->base.data + co->start_offs;
179 /* if calling the Coro we need the segment of the Coro */
180 else if (!(PObj_get_FLAGS(SELF) & SUB_FLAG_CORO_FF)) {
182 Stack_Chunk_t *state;
183 parrot_context_t *ctx;
185 PObj_get_FLAGS(SELF) |= SUB_FLAG_CORO_FF;
186 wanted_seg = co->seg;
188 /* remember segment of caller */
189 co->caller_seg = INTERP->code;
192 /* and the recent call context */
193 ccont = ctx->current_cont;
194 ctx->caller_ctx = PMC_cont(ccont)->to_ctx
197 /* set context to coro context */
198 state = interp->dynamic_env;
199 interp->dynamic_env = co->dynamic_state;
200 co->dynamic_state = state;
201 CONTEXT(interp) = ctx;
202 INTERP->ctx.bp = ctx->bp;
203 INTERP->ctx.bp_ps = ctx->bp_ps;
207 Stack_Chunk_t *state;
208 parrot_context_t *ctx;
210 PObj_get_FLAGS(SELF) &= ~SUB_FLAG_CORO_FF;
211 /* switch back to last remembered code seg and context */
213 wanted_seg = co->caller_seg;
214 ccont = co->ctx->current_cont;
215 ctx = PMC_cont(ccont)->to_ctx;
218 /* This still isn't quite right, but it beats segfaulting. See
219 the "Call an exited coroutine" case in t/pmc/coroutine.t; the
220 problem is that the defunct coroutine yields up one more
221 result before we get here. -- rgr, 7-Oct-06.
223 real_exception(INTERP, NULL, E_Exception,
224 "Cannot resume dead coroutine.");
227 state = interp->dynamic_env;
228 interp->dynamic_env = co->dynamic_state;
229 co->dynamic_state = state;
230 CONTEXT(interp) = ctx;
231 INTERP->ctx.bp = ctx->bp;
232 INTERP->ctx.bp_ps = ctx->bp_ps;
237 co->address = (opcode_t *)next;
239 if (INTERP->code != wanted_seg)
240 Parrot_switch_to_cs(INTERP, wanted_seg, 1);
249 Marks the coroutine as live.
256 Parrot_coro * const co = PMC_coro(SELF);
260 mark_context(INTERP, co->ctx);
261 if (co->dynamic_state)
262 mark_stack(INTERP, co->dynamic_state);
280 * c-file-style: "parrot"
282 * vim: expandtab shiftwidth=4: