fix codetest failure - ASSERT_ARGS does not have a ; after and
[parrot.git] / src / pmc / continuation.pmc
blob605d86dd9a74dee83efa9df2eb42b215bcec8be9
1 /*
2 Copyright (C) 2001-2010, 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
39 /* HEADERIZER HFILE: none */
40 /* HEADERIZER BEGIN: static */
41 /* HEADERIZER END: static */
45  * A Continuation (and an ExceptionHandler) has in its context a pointer
46  * to the register frame, which contains active objects.
47  * Additionally ct->current_cont has the continuation of the caller.
48  */
50 pmclass Continuation auto_attrs provides invokable {
51     /* continuation destination */
52     ATTR PackFile_ByteCode *seg;             /* bytecode segment */
53     ATTR opcode_t          *address;         /* start of bytecode, addr to continue */
54     ATTR PMC               *to_ctx;          /* pointer to dest context */
55     ATTR PMC               *to_call_object;  /* pointer to CallSignature */
56     /* a Continuation keeps the from_ctx alive */
57     ATTR PMC               *from_ctx;        /* sub, this cont is returning from */
58     ATTR int                runloop_id;      /* id of the creating runloop. */
59     ATTR int                invoked;         /* flag when a handler has been invoked. */
63 =item C<void init()>
65 Initializes the continuation.
67 =cut
71     VTABLE void init() {
72         PMC * const to_ctx = CURRENT_CONTEXT(INTERP);
74         SET_ATTR_to_ctx(INTERP, SELF, to_ctx);
75         SET_ATTR_to_call_object(INTERP, SELF, Parrot_pcc_get_signature(INTERP, to_ctx));
76         SET_ATTR_from_ctx(INTERP, SELF, CURRENT_CONTEXT(INTERP));
77         SET_ATTR_runloop_id(INTERP, SELF, 0);
78         SET_ATTR_seg(INTERP, SELF, INTERP->code);
79         SET_ATTR_address(INTERP, SELF, NULL);
81         PObj_custom_mark_SET(SELF);
82     }
87 =item C<void init_pmc(PMC *continuation)>
89 Initializes the continuation with values from the provided continuation.
91 =cut
96     /* if they pass in a PMC to initialize with */
97     VTABLE void init_pmc(PMC *values) {
98         PMC               *to_ctx;
99         opcode_t          *address;
100         PackFile_ByteCode *seg;
102         GET_ATTR_to_ctx(INTERP, values, to_ctx);
103         SET_ATTR_to_ctx(INTERP, SELF, to_ctx);
104         SET_ATTR_to_call_object(INTERP, SELF, Parrot_pcc_get_signature(INTERP, to_ctx));
106         SET_ATTR_from_ctx(INTERP, SELF, CURRENT_CONTEXT(INTERP));
107         SET_ATTR_runloop_id(INTERP, SELF, 0);
109         GET_ATTR_seg(INTERP, values, seg);
110         SET_ATTR_seg(INTERP, SELF, seg);
112         GET_ATTR_address(INTERP, values, address);
113         SET_ATTR_address(INTERP, SELF, address);
115         PObj_custom_mark_SET(SELF);
116     }
121 =item C<void mark()>
123 Marks the continuation as live.
125 =cut
129     VTABLE void mark() {
130         PMC *tmp;
132         /* If Continuation wasn't fully constructed yet */
133         if (!PMC_data(SELF))
134             return;
136         GET_ATTR_to_ctx(INTERP, SELF, tmp);
137         Parrot_gc_mark_PMC_alive(INTERP, tmp);
139         GET_ATTR_to_call_object(INTERP, SELF, tmp);
140         Parrot_gc_mark_PMC_alive(INTERP, tmp);
142         GET_ATTR_from_ctx(INTERP, SELF, tmp);
143         Parrot_gc_mark_PMC_alive(INTERP, tmp);
144     }
149 =item C<PMC *clone()>
151 Creates and returns a clone of the continuation.
153 =cut
157     VTABLE PMC *clone() {
158         /* Start to prepare for subclassable continuations */
159         return Parrot_pmc_new_init(INTERP, SELF->vtable->base_type, SELF);
160     }
165 =item C<PMC *set_pmc()>
167 Assigns context.
169 =cut
172     VTABLE void set_pmc(PMC *src) {
173         STRUCT_COPY(PMC_data_typed(SELF, Parrot_Continuation_attributes *),
174                     PMC_data_typed(src,  Parrot_Continuation_attributes *));
175     }
179 =item C<void set_pointer(void *value)>
181 Sets the pointer to the given return instruction and captures the runloop id
182 for any returned values.
184 =cut
188     VTABLE void set_pointer(void *value) {
189         SET_ATTR_address(INTERP, SELF, (opcode_t *)value);
190         SET_ATTR_runloop_id(INTERP, SELF, INTERP->current_runloop_id);
191     }
196 =item C<void *get_pointer()>
198 Returns the pointer to the return instruction.
200 =cut
204     VTABLE void *get_pointer() {
205         opcode_t          *address;
207         GET_ATTR_address(INTERP, SELF, address);
208         return address;
209     }
214 =item C<INTVAL defined()>
216 =item C<INTVAL get_bool()>
218 Returns whether the subroutine is defined.
220 =cut
224     VTABLE INTVAL defined() {
225         opcode_t          *address;
227         GET_ATTR_address(INTERP, SELF, address);
228         return address != NULL;
229     }
232     VTABLE INTVAL get_bool() {
233         opcode_t          *address;
235         GET_ATTR_address(INTERP, SELF, address);
236         return address != NULL;
237     }
242 =item C<opcode_t *invoke(void *next)>
244 Restores the context of the interpreter and returns the branch
245 destination to continue execution.
247 =cut
251     VTABLE opcode_t *invoke(void *next) {
252         PMC * const        from_obj = Parrot_pcc_get_signature(INTERP, CURRENT_CONTEXT(INTERP));
253         PMC               *to_ctx, *call_obj;
254         opcode_t          *pc;
255         PackFile_ByteCode *seg;
256         UNUSED(next)
258         GET_ATTR_seg(INTERP, SELF, seg);
259         GET_ATTR_address(INTERP, SELF, pc);
260         GET_ATTR_to_ctx(INTERP, SELF, to_ctx);
261         GET_ATTR_to_call_object(INTERP, SELF, call_obj);
263         Parrot_continuation_check(INTERP, SELF);
264         Parrot_continuation_rewind_environment(INTERP, SELF);
266         if (!PMC_IS_NULL(from_obj))
267             Parrot_pcc_set_signature(INTERP, CURRENT_CONTEXT(INTERP), from_obj);
269         /* switch segment */
270         if (INTERP->code != seg)
271             Parrot_switch_to_cs(INTERP, seg, 1);
273         return pc;
274     }
279 =item C<STRING *get_string()>
281 Experimental: returns caller info as a STRING.
283 =cut
287     VTABLE STRING *get_string() {
288         PMC *to_ctx;
290         GET_ATTR_to_ctx(INTERP, SELF, to_ctx);
291         return Parrot_Context_infostr(INTERP, to_ctx);
292     }
297 =item C<INTVAL rid()>
299 Experimental: return the runloop_id value.
301 =cut
305     METHOD rid() {
306         INTVAL runloop_id;
307         GET_ATTR_runloop_id(INTERP, SELF, runloop_id);
308         RETURN(INTVAL runloop_id);
309     }
313 =item C<PMC *caller()>
315 Experimental: return callers PMC or PMCNULL if none.
317 =cut
321     METHOD caller() {
322         PMC *to_ctx, *caller;
324         GET_ATTR_to_ctx(INTERP, SELF, to_ctx);
326         caller = Parrot_pcc_get_sub(INTERP, to_ctx);
328         if (!caller)
329             caller = PMCNULL;
330         else {
331             Parrot_Sub_attributes *sub;
332             PMC_get_sub(INTERP, caller, sub);
333             if (!sub->seg)
334                 caller = PMCNULL;
335         }
337         RETURN(PMC *caller);
339     }
344 =item C<PMC *continuation()>
346 Experimental: returns continuation PMC of this Continuation or PMCNULL if none.
348 =cut
352     METHOD continuation() {
353         PMC *to_ctx, *cont;
355         GET_ATTR_to_ctx(INTERP, SELF, to_ctx);
357         cont = Parrot_pcc_get_continuation(INTERP, to_ctx);
359         if (cont)
360             RETURN(PMC *cont);
362         RETURN(PMC *PMCNULL);
363     }
368 =back
370 =cut
375  * Local variables:
376  *   c-file-style: "parrot"
377  * End:
378  * vim: expandtab shiftwidth=4:
379  */