/
retcontinuation.pmc
118 lines (76 loc) · 2.3 KB
/
retcontinuation.pmc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*
Copyright (C) 2001-2008, Parrot Foundation.
$Id$
=head1 NAME
src/pmc/retcontinuation.pmc - Return Continuation
=head1 DESCRIPTION
C<RetContinuation> extends C<Continuation>.
A return continuation is a one shot Continuation. It gets recycled immediately
after invocation.
=head2 Methods
=over 4
=cut
*/
#include "parrot/oplib/ops.h"
/* HEADERIZER HFILE: none */
/* HEADERIZER BEGIN: static */
/* HEADERIZER END: static */
pmclass RetContinuation extends Continuation auto_attrs {
/*
=item C<void init()>
Initializes the continuation.
=cut
*/
VTABLE void init() {
Parrot_RetContinuation_attributes * const attrs = PARROT_RETCONTINUATION(SELF);
attrs->to_ctx = CURRENT_CONTEXT(interp);
attrs->from_ctx = PMCNULL; /* filled in during a call */
attrs->runloop_id = 0;
attrs->seg = interp->code;
attrs->address = NULL;
}
/*
=item C<PMC *clone>
Return a new Continuation PMC with the context of SELF. Note: the returned
object is not a RetContinuation and creating a real Continuation invalidates
all RetContinuation all the way up the call chain. That is, these can't be
recycled; they persist until the GC gets at them.
=cut
*/
VTABLE PMC *clone() {
invalidate_retc_context(INTERP, SELF);
return SUPER();
}
/*
=item C<opcode_t *invoke(void *next)>
Transfers control to the calling context and frees the current context.
=cut
*/
VTABLE opcode_t *invoke(void *in_next) {
Parrot_Continuation_attributes *data = PARROT_CONTINUATION(SELF);
PMC *from_ctx = data->from_ctx;
PackFile_ByteCode * const seg = data->seg;
opcode_t *next = data->address;
UNUSED(in_next)
Parrot_continuation_check(interp, SELF);
Parrot_continuation_rewind_environment(interp, SELF);
/* recycle this PMC and make sure it doesn't get marked */
if (!PMC_IS_NULL(from_ctx))
Parrot_pcc_set_continuation(interp, from_ctx, NULL);
if (INTERP->code != seg)
Parrot_switch_to_cs(INTERP, seg, 1);
return next;
}
}
/*
=back
=head1 HISTORY
Initial revision by sean 2002/08/04.
=cut
*/
/*
* Local variables:
* c-file-style: "parrot"
* End:
* vim: expandtab shiftwidth=4:
*/