2 Copyright (C) 2001-2008, 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"
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.
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. */
60 Initializes the continuation.
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"); */
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.
85 invalidate_retc_context(INTERP, SELF);
88 /*if they pass in a PMC to initialize with*/
89 VTABLE void init_pmc(PMC *values) {
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"); */
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.
116 invalidate_retc_context(INTERP, SELF);
125 Marks the continuation as live.
134 /* If Continuation wasn't fully constructed yet */
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);
150 =item C<PMC *clone()>
152 Creates and returns a clone of the continuation.
158 VTABLE PMC *clone() {
159 /* Start to prepare for subclassable continuations */
160 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((Parrot_Continuation_attributes *)PMC_data(SELF),
174 (Parrot_Continuation_attributes *)PMC_data(src));
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.
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);
194 =item C<void *get_pointer()>
196 Returns the pointer to the return instruction.
202 VTABLE void *get_pointer() {
205 GET_ATTR_address(INTERP, SELF, address);
212 =item C<INTVAL defined()>
214 =item C<INTVAL get_bool()>
216 Returns whether the subroutine is defined.
222 VTABLE INTVAL defined() {
225 GET_ATTR_address(INTERP, SELF, address);
227 return address != NULL;
230 VTABLE INTVAL get_bool() {
233 GET_ATTR_address(INTERP, SELF, address);
235 return address != NULL;
240 =item C<opcode_t *invoke(void *next)>
242 Restores the context of the interpreter and returns the branch
243 destination to continue execution.
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;
253 PackFile_ByteCode *seg;
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);
269 if (INTERP->code != seg)
270 Parrot_switch_to_cs(INTERP, seg, 1);
277 =item C<STRING *get_string()>
279 Experimental: return caller info as a STRING.
285 VTABLE STRING *get_string() {
288 GET_ATTR_to_ctx(INTERP, SELF, to_ctx);
290 return Parrot_Context_infostr(INTERP, to_ctx);
295 =item C<PMC *caller()>
297 Experimental: return caller PMC or PMCNULL if none.
304 PMC *to_ctx, *caller;
306 GET_ATTR_to_ctx(INTERP, SELF, to_ctx);
308 caller = Parrot_pcc_get_sub(INTERP, to_ctx);
313 Parrot_Sub_attributes *sub;
314 PMC_get_sub(INTERP, caller, sub);
324 =item C<PMC *continuation()>
326 Experimental: return continuation PMC of this Continuation or PMCNULL if none.
332 METHOD continuation() {
335 GET_ATTR_to_ctx(INTERP, SELF, to_ctx);
337 cont = Parrot_pcc_get_continuation(INTERP, to_ctx);
342 RETURN(PMC *PMCNULL);
352 Initial revision by sean 2002/08/04.
360 * c-file-style: "parrot"
362 * vim: expandtab shiftwidth=4: