fix codetest failure - trailing whitespace
[parrot.git] / src / pmc / continuation.pmc
blobdf18455db18d95c21db521b61d37e25677759930
1 /*
2 Copyright (C) 2001-2008, Parrot Foundation.
3 $Id$
5 =head1 NAME
7 src/pmc/continuation.pmc - Continuation PMC
9 =head1 DESCRIPTION
11 A C<Continuation> has a copy of the interpreter's context at the location where
12 the Continuation was constructed.  See the L<Glossary|docs/glossary.pod> for
13 more information.
15 =head2 Functions
17 =over 4
19 =cut
24 #include "parrot/oplib/ops.h"
25 #include "pmc/pmc_sub.h"
29 =back
31 =head2 Methods
33 =over 4
35 =cut
41  * A Continuation (and RetContinuation, ExceptionHandler) has in its
42  * context a pointer to the register frame, which contains active objects.
43  * Additionally ct->current_cont has the continuation of the caller.
44  */
46 pmclass Continuation auto_attrs {
47     /* continuation destination */
48     ATTR PackFile_ByteCode *seg;             /* bytecode segment */
49     ATTR opcode_t          *address;         /* start of bytecode, addr to continue */
50     ATTR PMC               *to_ctx;          /* pointer to dest context */
51     ATTR PMC               *to_call_object;  /* pointer to CallSignature */
52     /* a Continuation keeps the from_ctx alive */
53     ATTR PMC               *from_ctx;        /* sub, this cont is returning from */
54     ATTR int                runloop_id;      /* id of the creating runloop. */
55     ATTR int                invoked;         /* flag when a handler has been invoked. */
58 =item C<void init()>
60 Initializes the continuation.
62 =cut
66     VTABLE void init() {
67         PMC * const to_ctx = CURRENT_CONTEXT(INTERP);
69         SET_ATTR_to_ctx(INTERP, SELF, to_ctx);
70         SET_ATTR_to_call_object(INTERP, SELF, Parrot_pcc_get_signature(INTERP, to_ctx));
71         SET_ATTR_from_ctx(INTERP, SELF, CURRENT_CONTEXT(INTERP));
72         SET_ATTR_runloop_id(INTERP, SELF, 0);
73         SET_ATTR_seg(INTERP, SELF, INTERP->code);
74         SET_ATTR_address(INTERP, SELF, NULL);
76         PObj_custom_mark_SET(SELF);
78         /* PANIC("don't do that"); */
79         /*
80          * Whenever we create a continuation, all return continuations
81          * up the call chain may be reused due to invoking the
82          * continuation. To avoid that all return continuations are
83          * converted to true continuations.
84          */
85         invalidate_retc_context(INTERP, SELF);
86     }
88     /*if they pass in a PMC to initialize with*/
89     VTABLE void init_pmc(PMC *values) {
90         PMC               *to_ctx;
91         opcode_t          *address;
92         PackFile_ByteCode *seg;
94         GET_ATTR_to_ctx(INTERP, values, to_ctx);
95         SET_ATTR_to_ctx(INTERP, SELF, to_ctx);
96         SET_ATTR_to_call_object(INTERP, SELF, Parrot_pcc_get_signature(INTERP, to_ctx));
98         SET_ATTR_from_ctx(INTERP, SELF, CURRENT_CONTEXT(INTERP));
99         SET_ATTR_runloop_id(INTERP, SELF, 0);
101         GET_ATTR_seg(INTERP, values, seg);
102         SET_ATTR_seg(INTERP, SELF, seg);
104         GET_ATTR_address(INTERP, values, address);
105         SET_ATTR_address(INTERP, SELF, address);
107         PObj_custom_mark_SET(SELF);
109         /* PANIC("don't do that"); */
110         /*
111          * Whenever we create a continuation, all return continuations
112          * up the call chain may be reused due to invoking the
113          * continuation. To avoid that all return continuations are
114          * converted to true continuations.
115          */
116         invalidate_retc_context(INTERP, SELF);
117     }
123 =item C<void mark()>
125 Marks the continuation as live.
127 =cut
131     VTABLE void mark() {
132         PMC *tmp;
134         /* If Continuation wasn't fully constructed yet */
135         if (!PMC_data(SELF))
136             return;
138         GET_ATTR_to_ctx(INTERP, SELF, tmp);
139         Parrot_gc_mark_PMC_alive(INTERP, tmp);
141         GET_ATTR_to_call_object(INTERP, SELF, tmp);
142         Parrot_gc_mark_PMC_alive(INTERP, tmp);
144         GET_ATTR_from_ctx(INTERP, SELF, tmp);
145         Parrot_gc_mark_PMC_alive(INTERP, tmp);
146     }
150 =item C<PMC *clone()>
152 Creates and returns a clone of the continuation.
154 =cut
158     VTABLE PMC *clone() {
159         /* Start to prepare for subclassable continuations */
160         return Parrot_pmc_new_init(INTERP, SELF->vtable->base_type, SELF);
161     }
165 =item C<PMC *set_pmc()>
167 Assign context.
169 =cut
172     VTABLE void set_pmc(PMC *src) {
173         STRUCT_COPY((Parrot_Continuation_attributes *)PMC_data(SELF),
174                 (Parrot_Continuation_attributes *)PMC_data(src));
175     }
178 =item C<void set_pointer(void *value)>
180 Sets the pointer to the return instruction.  Also captures the descriptor
181 address for any returned values.
183 =cut
187     VTABLE void set_pointer(void *value) {
188         SET_ATTR_address(INTERP, SELF, (opcode_t *)value);
189         SET_ATTR_runloop_id(INTERP, SELF, INTERP->current_runloop_id);
190     }
194 =item C<void *get_pointer()>
196 Returns the pointer to the return instruction.
198 =cut
202     VTABLE void *get_pointer() {
203         opcode_t          *address;
205         GET_ATTR_address(INTERP, SELF, address);
207         return address;
208     }
212 =item C<INTVAL defined()>
214 =item C<INTVAL get_bool()>
216 Returns whether the subroutine is defined.
218 =cut
222     VTABLE INTVAL defined() {
223         opcode_t          *address;
225         GET_ATTR_address(INTERP, SELF, address);
227         return address != NULL;
228     }
230     VTABLE INTVAL get_bool() {
231         opcode_t          *address;
233         GET_ATTR_address(INTERP, SELF, address);
235         return address != NULL;
236     }
240 =item C<opcode_t *invoke(void *next)>
242 Restores the context of the interpreter and returns the branch
243 destination to continue execution.
245 =cut
249     VTABLE opcode_t *invoke(void *next) {
250         PMC * const        from_obj = Parrot_pcc_get_signature(INTERP, CURRENT_CONTEXT(INTERP));
251         PMC               *to_ctx, *call_obj;
252         opcode_t          *pc;
253         PackFile_ByteCode *seg;
254         UNUSED(next)
256         GET_ATTR_seg(INTERP, SELF, seg);
257         GET_ATTR_address(INTERP, SELF, pc);
258         GET_ATTR_to_ctx(INTERP, SELF, to_ctx);
259         GET_ATTR_to_call_object(INTERP, SELF, call_obj);
261         Parrot_continuation_check(INTERP, SELF);
262         Parrot_continuation_rewind_environment(INTERP, SELF);
264         if (!PMC_IS_NULL(from_obj)) {
265             Parrot_pcc_set_signature(INTERP, CURRENT_CONTEXT(INTERP), from_obj);
266         }
268         /* switch segment */
269         if (INTERP->code != seg)
270             Parrot_switch_to_cs(INTERP, seg, 1);
272         return pc;
273     }
277 =item C<STRING *get_string()>
279 Experimental: return caller info as a STRING.
281 =cut
285     VTABLE STRING *get_string() {
286         PMC *to_ctx;
288         GET_ATTR_to_ctx(INTERP, SELF, to_ctx);
290         return Parrot_Context_infostr(INTERP, to_ctx);
291     }
295 =item C<PMC *caller()>
297 Experimental: return caller PMC or PMCNULL if none.
299 =cut
303     METHOD caller() {
304         PMC *to_ctx, *caller;
306         GET_ATTR_to_ctx(INTERP, SELF, to_ctx);
308         caller = Parrot_pcc_get_sub(INTERP, to_ctx);
310         if (!caller)
311             caller = PMCNULL;
312         else {
313             Parrot_Sub_attributes *sub;
314             PMC_get_sub(INTERP, caller, sub);
315             if (!sub->seg)
316                 caller = PMCNULL;
317         }
319         RETURN(PMC *caller);
321     }
324 =item C<PMC *continuation()>
326 Experimental: return continuation PMC of this Continuation or PMCNULL if none.
328 =cut
332     METHOD continuation() {
333         PMC *to_ctx, *cont;
335         GET_ATTR_to_ctx(INTERP, SELF, to_ctx);
337         cont = Parrot_pcc_get_continuation(INTERP, to_ctx);
339         if (cont)
340             RETURN(PMC *cont);
342         RETURN(PMC *PMCNULL);
343     }
348 =back
350 =head1 HISTORY
352 Initial revision by sean 2002/08/04.
354 =cut
359  * Local variables:
360  *   c-file-style: "parrot"
361  * End:
362  * vim: expandtab shiftwidth=4:
363  */