2 Copyright (C) 2001-2003, The Perl Foundation.
7 src/pmc/continuation.pmc - Continuation PMC
11 A C<Continuation> has a copy of the interpreter's context at the location,
12 where the Continuation was constructed.
13 See the L<Glossary|docs/glossary.pod> for more information.
24 #include "parrot/parrot.h"
25 #include "parrot/oplib/ops.h"
43 * A Continuation (and RetContinuation, Exception_Handler) has in its
44 * context a pointer to the register frame, which contains active objects.
45 * Additionally ct->current_cont has he continuation of the caller.
46 * To avoid deep recursion during marking of nested subroutines, we
47 * need the next_for_GC pointer in the pmc_ext area.
50 pmclass Continuation need_ext {
56 Initializes the continuation.
63 PMC_struct_val(SELF) = new_continuation(INTERP, NULL);
64 PMC_pmc_val(SELF) = NULL;
65 PObj_custom_mark_destroy_SETALL(SELF);
66 /* PANIC("don't do that"); */
68 * Whenever we create a continuation, all return continuations
69 * up the call chain maybe reused due to invoking the
70 * continuation. To avoid that all return continuations are
71 * converted to true continuations.
73 invalidate_retc_context(INTERP, SELF);
80 Marks the continuation as live.
87 struct Parrot_cont * cc = PMC_cont(SELF);
89 mark_context(INTERP, cc->to_ctx);
90 if (cc->dynamic_state)
91 mark_register_stack(INTERP, cc->dynamic_state);
96 =item C<void destroy()>
98 Destroys the continuation.
105 struct Parrot_cont * cc = PMC_cont(SELF);
108 if (Interp_debug_TEST(interpreter, PARROT_CTX_DESTROY_DEBUG_FLAG)) {
110 "[destroy cont %p, to_ctx %p, from_ctx %p]\n",
111 SELF, cc->to_ctx, cc->from_ctx);
115 Parrot_free_context(interpreter, cc->from_ctx, 0);
117 PMC_struct_val(SELF) = NULL;
122 =item C<PMC *clone()>
124 Creates and returns a clone of the continuation.
131 struct Parrot_cont * cc;
132 struct Parrot_cont *cc_self = PMC_cont(SELF);
133 PMC* ret = pmc_new_noinit(INTERP, enum_class_Continuation);
135 PObj_custom_mark_destroy_SETALL(ret);
136 cc = new_continuation(INTERP, cc_self);
137 cc->runloop_id = cc_self->runloop_id;
138 cc->dynamic_state = cc_self->dynamic_state;
139 PMC_struct_val(ret) = cc;
140 PMC_pmc_val(ret) = PMC_pmc_val(SELF);
146 =item C<PMC *set_pmc()>
153 void set_pmc(PMC* src) {
154 struct Parrot_cont *cc_self = PMC_cont(SELF);
155 struct Parrot_cont *cc_src = PMC_cont(src);
157 memcpy(cc_self, cc_src, sizeof(struct Parrot_cont));
158 PMC_pmc_val(SELF) = PMC_pmc_val(src);
162 =item C<void set_pointer(void *value)>
164 Sets the pointer to the return instruction.
170 void set_pointer (void* value) {
171 opcode_t *pos = value;
172 struct Parrot_cont * cc = PMC_cont(SELF);
174 PObj_get_FLAGS(SELF) |= PObj_private1_FLAG;
176 cc->dynamic_state = CONTEXT(INTERP->ctx)->control_stack;
177 cc->runloop_id = INTERP->current_runloop_id;
178 if (pos && *pos == PARROT_OP_get_results_pc) {
179 cc->current_results = pos;
182 cc->current_results = NULL;
187 =item C<void *get_pointer()>
189 Returns the pointer to the return instruction.
195 void* get_pointer () {
196 return PMC_cont(SELF)->address;
200 =item C<INTVAL defined()>
202 =item C<INTVAL get_bool()>
204 Returns whether the subroutine is defined.
211 return PMC_cont(SELF)->address != NULL;
215 return PMC_cont(SELF)->address != NULL;
220 =item C<void *invoke(void *next)>
222 Restores the "context" of the interpreter and returns the branch
223 destination to continue execution.
229 void* invoke (void* next) {
230 struct Parrot_cont * cc = PMC_cont(SELF);
231 Stack_Chunk_t *stack_target = cc->dynamic_state;
232 Stack_Chunk_t *corresponding_target;
234 parrot_context_t *from_ctx = CONTEXT(INTERP->ctx);
235 parrot_context_t *to_ctx = cc->to_ctx;
236 opcode_t *pc = cc->address;
237 /* [bug: these should be 'isa' tests. -- rgr, 17-Sep-06.] */
238 int exception_continuation_p
239 = SELF->vtable->base_type == enum_class_Exception_Handler;
240 int ret_continuation_p
241 = SELF->vtable->base_type == enum_class_RetContinuation;
243 if (interpreter->current_runloop_id != cc->runloop_id
244 /* it's ok if we are exiting to "runloop 0"; there is no such
245 runloop, but the only continuation that thinks it came from
246 runloop 0 is for the return from the initial sub call. */
247 && cc->runloop_id != 0
248 /* since a RetContinuation [currently] only returns to the next
249 outer frame, exiting to the inner run loop does the right thing,
250 since it normally returns to the next outer runloop anyway. */
251 && ! ret_continuation_p) {
252 fprintf(stderr, "[oops; continuation %p of type %d "
253 "is trying to jump from runloop %d to runloop %d]\n",
254 SELF, (int) SELF->vtable->base_type,
255 interpreter->current_runloop_id, cc->runloop_id);
258 if (Interp_debug_TEST(interpreter, PARROT_CTX_DESTROY_DEBUG_FLAG)) {
260 "[invoke cont %p, to_ctx %p, from_ctx %p (refs %d)]\n",
261 SELF, to_ctx, from_ctx, (int) from_ctx->ref_count);
265 real_exception(interpreter, NULL, INVALID_OPERATION,
266 "Continuation invoked after deactivation.");
270 * rewind control stack
272 if (from_ctx->control_stack != stack_target) {
273 /* compute the "stack delta", which is a measure of how much
274 unwinding we have to do. if negative, we have to pop that many
275 entries; if positive, we are going back up the stack.
276 [bug: this is not true rewinding. -- rgr, 30-Sep-06.]
279 = ((int) stack_height(interpreter, stack_target)
280 - (int) stack_height(interpreter, from_ctx->control_stack));
282 /* descend down the target stack until we get to the same depth. */
283 corresponding_target = stack_target;
284 while (stack_delta > 0) {
285 corresponding_target = corresponding_target->prev;
288 /* both stacks are now at the same depth. pop from both until we reach
289 their common ancestor. */
290 while (from_ctx->control_stack != corresponding_target) {
291 PMC *cleanup_sub = NULL;
294 if (! from_ctx->control_stack)
295 internal_exception(1, "Control stack damaged");
296 e = stack_entry(interpreter, from_ctx->control_stack, 0);
298 internal_exception(1, "Control stack damaged");
299 if (e->entry_type == STACK_ENTRY_ACTION) {
301 * Disable automatic cleanup routine execution in stack_pop so
302 * that we can run the action subroutine manually. This is
303 * because we have to run the sub AFTER it has been popped, lest
304 * a new error in the sub cause an infinite loop when invoking
307 cleanup_sub = UVal_pmc(e->entry);
308 e->cleanup = STACK_CLEANUP_NULL;
310 (void)stack_pop(INTERP, &from_ctx->control_stack,
311 NULL, NO_STACK_ENTRY_TYPE);
313 /* Now it's safe to run. */
314 Parrot_runops_fromc_args(interpreter, cleanup_sub,
315 "vI", exception_continuation_p);
317 corresponding_target = corresponding_target->prev;
319 /* run back up the target stack to our destination. [when we support
320 dynamic binding (e.g.), we will have to traverse back up, and will
321 therefore need to keep track on the way down. -- rgr, 30-Sep-06.] */
322 to_ctx->control_stack = stack_target;
324 /* debug print before context is switched */
325 if (Interp_trace_TEST(INTERP, PARROT_TRACE_SUB_CALL_FLAG)) {
326 PMC *sub = to_ctx->current_sub;
328 PIO_eprintf(INTERP, "# Back in sub '%Ss'\n",
329 Parrot_full_sub_name(INTERP, sub));
335 CONTEXT(INTERP->ctx) = to_ctx;
336 INTERP->ctx.bp = to_ctx->bp;
337 INTERP->ctx.bp_ps = to_ctx->bp_ps;
338 if (ret_continuation_p) {
339 /* RetContinuation arg passing is handled elsewhere. */
344 if (cc->current_results) {
345 /* where caller wants result */
346 to_ctx->current_results = cc->current_results;
348 if (to_ctx->current_results && INTERP->current_args) {
350 * the register pointer is already switched back
351 * to the caller, therefore the registers of the
352 * sub we are returning from aren't marked, if
353 * inside argument passing a DOD run is triggered
354 * therefore we have to block DOD
356 Parrot_block_DOD(INTERP);
357 parrot_pass_args(INTERP,
360 PARROT_OP_set_args_pc);
361 Parrot_unblock_DOD(INTERP);
365 INTERP->current_args = NULL;
366 if (INTERP->code != cc->seg) {
367 Parrot_switch_to_cs(INTERP, cc->seg, 1);
374 =item C<STRING* get_string()>
376 Experimental: return caller info as a STRING.
382 STRING* get_string() {
383 return Parrot_Context_infostr(INTERP, PMC_cont(SELF)->to_ctx);
388 =item C<METHOD PMC* "caller"()>
390 Experimental: return caller PMC or Undef if none.
396 METHOD PMC* caller() {
397 struct Parrot_cont * cc = PMC_cont(SELF);
398 PMC *caller = cc->to_ctx->current_sub;
399 if (!caller || !PMC_sub(caller)->seg) {
400 caller = pmc_new(INTERP, enum_class_Undef);
407 =item C<METHOD PMC* "continuation"()>
409 Experimental: return continuation PMC of this Continuation or Undef if none.
415 METHOD PMC* continuation() {
416 struct Parrot_cont * cc = PMC_cont(SELF);
417 PMC *cont = cc->to_ctx->current_cont;
420 return pmc_new(INTERP, enum_class_Undef);
430 Initial revision by sean 2002/08/04.
438 * c-indentation-style: bsd
440 * indent-tabs-mode: nil
443 * vim: expandtab shiftwidth=4: