2 Copyright (C) 2001-2010, Parrot Foundation.
7 src/pmc/continuation.pmc - Continuation PMC
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
24 #include "parrot/oplib/ops.h"
25 #include "pmc/pmc_sub.h"
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.
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. */
65 Initializes the continuation.
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);
87 =item C<void init_pmc(PMC *continuation)>
89 Initializes the continuation with values from the provided continuation.
96 /* if they pass in a PMC to initialize with */
97 VTABLE void init_pmc(PMC *values) {
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);
123 Marks the continuation as live.
132 /* If Continuation wasn't fully constructed yet */
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);
149 =item C<PMC *clone()>
151 Creates and returns a clone of the continuation.
157 VTABLE PMC *clone() {
158 /* Start to prepare for subclassable continuations */
159 return Parrot_pmc_new_init(INTERP, SELF->vtable->base_type, SELF);
165 =item C<PMC *set_pmc()>
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 *));
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.
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);
196 =item C<void *get_pointer()>
198 Returns the pointer to the return instruction.
204 VTABLE void *get_pointer() {
207 GET_ATTR_address(INTERP, SELF, address);
214 =item C<INTVAL defined()>
216 =item C<INTVAL get_bool()>
218 Returns whether the subroutine is defined.
224 VTABLE INTVAL defined() {
227 GET_ATTR_address(INTERP, SELF, address);
228 return address != NULL;
232 VTABLE INTVAL get_bool() {
235 GET_ATTR_address(INTERP, SELF, address);
236 return address != NULL;
242 =item C<opcode_t *invoke(void *next)>
244 Restores the context of the interpreter and returns the branch
245 destination to continue execution.
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;
255 PackFile_ByteCode *seg;
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);
270 if (INTERP->code != seg)
271 Parrot_switch_to_cs(INTERP, seg, 1);
279 =item C<STRING *get_string()>
281 Experimental: returns caller info as a STRING.
287 VTABLE STRING *get_string() {
290 GET_ATTR_to_ctx(INTERP, SELF, to_ctx);
291 return Parrot_Context_infostr(INTERP, to_ctx);
297 =item C<INTVAL rid()>
299 Experimental: return the runloop_id value.
307 GET_ATTR_runloop_id(INTERP, SELF, runloop_id);
308 RETURN(INTVAL runloop_id);
313 =item C<PMC *caller()>
315 Experimental: return callers PMC or PMCNULL if none.
322 PMC *to_ctx, *caller;
324 GET_ATTR_to_ctx(INTERP, SELF, to_ctx);
326 caller = Parrot_pcc_get_sub(INTERP, to_ctx);
331 Parrot_Sub_attributes *sub;
332 PMC_get_sub(INTERP, caller, sub);
344 =item C<PMC *continuation()>
346 Experimental: returns continuation PMC of this Continuation or PMCNULL if none.
352 METHOD continuation() {
355 GET_ATTR_to_ctx(INTERP, SELF, to_ctx);
357 cont = Parrot_pcc_get_continuation(INTERP, to_ctx);
362 RETURN(PMC *PMCNULL);
376 * c-file-style: "parrot"
378 * vim: expandtab shiftwidth=4: