Ticket #1377: continuation.c

File continuation.c, 16.4 KB (added by baest, 5 years ago)
Line 
1/* ex: set ro ft=c:
2 * !!!!!!!   DO NOT EDIT THIS FILE   !!!!!!!
3 *
4 * This file is generated automatically from './src/pmc/continuation.pmc'
5 * by tools/build/pmc2c.pl.
6 *
7 * Any changes made here will be lost!
8 *
9 */
10
11/* HEADERIZER HFILE: none */
12/* HEADERIZER STOP */
13
14#include "parrot/parrot.h"
15#include "parrot/extend.h"
16#include "parrot/dynext.h"
17#include "pmc_fixedintegerarray.h"
18#include "pmc_continuation.h"
19#include "pmc_default.h"
20#include "continuation.str"
21#include "pmc/pmc_continuation.h"
22#include "pmc/pmc_context.h"
23#line 1 "./src/pmc/continuation.pmc"
24/*
25Copyright (C) 2001-2008, Parrot Foundation.
26$Id: continuation.pmc 42440 2009-11-12 09:49:10Z bacek $
27
28=head1 NAME
29
30src/pmc/continuation.pmc - Continuation PMC
31
32=head1 DESCRIPTION
33
34A C<Continuation> has a copy of the interpreter's context at the location where
35the Continuation was constructed.  See the L<Glossary|docs/glossary.pod> for
36more information.
37
38=head2 Functions
39
40=over 4
41
42=cut
43
44*/
45
46
47#include "parrot/oplib/ops.h"
48#include "pmc/pmc_sub.h"
49
50/*
51
52=back
53
54=head2 Methods
55
56=over 4
57
58=cut
59
60*/
61
62
63/*
64 * A Continuation (and RetContinuation, ExceptionHandler) has in its
65 * context a pointer to the register frame, which contains active objects.
66 * Additionally ct->current_cont has the continuation of the caller.
67 */
68#line 68 "./src/pmc/continuation.c"
69static  PMC  * Parrot_Continuation_clone(PARROT_INTERP, PMC *pmc);
70static  INTVAL  Parrot_Continuation_defined(PARROT_INTERP, PMC *pmc);
71static  INTVAL  Parrot_Continuation_get_bool(PARROT_INTERP, PMC *pmc);
72static  void  * Parrot_Continuation_get_pointer(PARROT_INTERP, PMC *pmc);
73static  STRING  * Parrot_Continuation_get_string(PARROT_INTERP, PMC *pmc);
74static  void  Parrot_Continuation_init(PARROT_INTERP, PMC *pmc);
75static  void  Parrot_Continuation_init_pmc(PARROT_INTERP, PMC *pmc, PMC *values);
76static  opcode_t  * Parrot_Continuation_invoke(PARROT_INTERP, PMC *pmc, void *next);
77static  void  Parrot_Continuation_mark(PARROT_INTERP, PMC *pmc);
78static  void  Parrot_Continuation_set_pmc(PARROT_INTERP, PMC *pmc, PMC *src);
79static  void  Parrot_Continuation_set_pointer(PARROT_INTERP, PMC *pmc, void *value);
80static  void Parrot_Continuation_nci_caller(PARROT_INTERP, PMC *pmc);
81static  void Parrot_Continuation_nci_continuation(PARROT_INTERP, PMC *pmc);
82void    Parrot_Continuation_class_init(PARROT_INTERP, int, int);
83PARROT_EXPORT VTABLE* Parrot_Continuation_update_vtable(ARGMOD(VTABLE*));
84PARROT_EXPORT VTABLE* Parrot_Continuation_get_vtable(PARROT_INTERP);
85void    Parrot_Continuation_ro_class_init(PARROT_INTERP, int, int);
86PARROT_EXPORT VTABLE* Parrot_Continuation_ro_update_vtable(ARGMOD(VTABLE*));
87PARROT_EXPORT VTABLE* Parrot_Continuation_ro_get_vtable(PARROT_INTERP);
88static  PMC  *
89Parrot_Continuation_clone(PARROT_INTERP, PMC *pmc)
90{
91#line 146 "./src/pmc/continuation.pmc"
92
93    /* Start to prepare for subclassable continuations */
94    INTVAL type = pmc->vtable->base_type;
95    PMC * ret = pmc_new_init(interp, type, pmc);
96    return ret;
97#line 97 "./src/pmc/continuation.c"
98}
99static  INTVAL
100Parrot_Continuation_defined(PARROT_INTERP, PMC *pmc)
101{
102#line 213 "./src/pmc/continuation.pmc"
103
104    return PARROT_CONTINUATION(pmc)->address != NULL;
105#line 105 "./src/pmc/continuation.c"
106}
107static  INTVAL
108Parrot_Continuation_get_bool(PARROT_INTERP, PMC *pmc)
109{
110#line 217 "./src/pmc/continuation.pmc"
111
112    return PARROT_CONTINUATION(pmc)->address != NULL;
113#line 113 "./src/pmc/continuation.c"
114}
115static  void  *
116Parrot_Continuation_get_pointer(PARROT_INTERP, PMC *pmc)
117{
118#line 197 "./src/pmc/continuation.pmc"
119
120    return PARROT_CONTINUATION(pmc)->address;
121#line 121 "./src/pmc/continuation.c"
122}
123static  STRING  *
124Parrot_Continuation_get_string(PARROT_INTERP, PMC *pmc)
125{
126#line 277 "./src/pmc/continuation.pmc"
127
128    return Parrot_Context_infostr(interp, PARROT_CONTINUATION(pmc)->to_ctx);
129#line 129 "./src/pmc/continuation.c"
130}
131static  void 
132Parrot_Continuation_init(PARROT_INTERP, PMC *pmc)
133{
134#line 66 "./src/pmc/continuation.pmc"
135
136    Parrot_Continuation_attributes * const attrs = PARROT_CONTINUATION(pmc);
137
138    attrs->to_ctx           = CURRENT_CONTEXT(interp);
139    attrs->to_call_object   = Parrot_pcc_get_signature(interp, attrs->to_ctx);
140    attrs->from_ctx         = CURRENT_CONTEXT(interp);
141    attrs->runloop_id       = 0;
142    attrs->seg              = interp->code;
143    attrs->address          = NULL;
144
145    PObj_custom_mark_SET(pmc);
146
147    /* PANIC("don't do that"); */
148    /*
149     * Whenever we create a continuation, all return continuations
150     * up the call chain may be reused due to invoking the
151     * continuation. To avoid that all return continuations are
152     * converted to true continuations.
153     */
154    invalidate_retc_context(interp, pmc);
155#line 155 "./src/pmc/continuation.c"
156}
157static  void 
158Parrot_Continuation_init_pmc(PARROT_INTERP, PMC *pmc, PMC *values)
159{
160#line 89 "./src/pmc/continuation.pmc"
161
162    Parrot_Continuation_attributes * const attrs  = PARROT_CONTINUATION(pmc);
163    Parrot_Continuation_attributes * const theirs = PARROT_CONTINUATION(values);
164
165    attrs->to_ctx           = theirs->to_ctx;
166    attrs->to_call_object   = Parrot_pcc_get_signature(interp, attrs->to_ctx);
167    attrs->from_ctx         = CURRENT_CONTEXT(interp);
168    attrs->runloop_id       = 0;
169    attrs->seg              = theirs->seg;
170    attrs->address          = theirs->address;
171
172    PObj_custom_mark_SET(pmc);
173
174    /* PANIC("don't do that"); */
175    /*
176     * Whenever we create a continuation, all return continuations
177     * up the call chain may be reused due to invoking the
178     * continuation. To avoid that all return continuations are
179     * converted to true continuations.
180     */
181    invalidate_retc_context(interp, pmc);
182#line 182 "./src/pmc/continuation.c"
183}
184static  opcode_t  *
185Parrot_Continuation_invoke(PARROT_INTERP, PMC *pmc, void *next)
186{
187#line 232 "./src/pmc/continuation.pmc"
188
189    Parrot_Continuation_attributes * const cc = PARROT_CONTINUATION(pmc);
190    PMC      *from_ctx = CURRENT_CONTEXT(interp);
191    PMC      *to_ctx   = cc->to_ctx;
192    opcode_t *pc       = cc->address;
193    PMC      *call_obj = cc->to_call_object;
194    PMC      *from_obj = Parrot_pcc_get_signature(interp, from_ctx);
195    UNUSED(next)
196
197    Parrot_continuation_check(interp, pmc);
198    Parrot_continuation_rewind_environment(interp, pmc);
199
200    if (!PMC_IS_NULL(from_obj)) {
201        STRING *string_sig = VTABLE_get_string(interp, from_obj);
202        /* If there is no string - there is no args */
203        if (string_sig) {
204            PMC *raw_sig, *invalid_sig;
205            Parrot_pcc_parse_signature_string(interp, string_sig, &raw_sig, &invalid_sig);
206
207            /* Build results signature for continuation */
208            if (*pc == PARROT_OP_get_results_pc)
209                call_obj = Parrot_pcc_build_sig_object_returns_from_op(interp, call_obj,
210                    Parrot_pcc_get_pmc_constant(interp, to_ctx, pc[1]), pc);
211
212            Parrot_pcc_fill_returns_from_continuation(interp, call_obj, raw_sig, from_obj);
213        }
214    }
215
216    /* switch segment */
217    if (interp->code != cc->seg)
218        Parrot_switch_to_cs(interp, cc->seg, 1);
219
220    return pc;
221#line 221 "./src/pmc/continuation.c"
222}
223static  void 
224Parrot_Continuation_mark(PARROT_INTERP, PMC *pmc)
225{
226#line 124 "./src/pmc/continuation.pmc"
227
228    Parrot_Continuation_attributes * const cc = PARROT_CONTINUATION(pmc);
229
230    /* If Continuation wasn't fully constructed yet */
231    if (!cc)
232        return;
233
234    Parrot_gc_mark_PMC_alive(interp, cc->to_ctx);
235    Parrot_gc_mark_PMC_alive(interp, cc->to_call_object);
236    Parrot_gc_mark_PMC_alive(interp, cc->from_ctx);
237#line 237 "./src/pmc/continuation.c"
238}
239static  void 
240Parrot_Continuation_set_pmc(PARROT_INTERP, PMC *pmc, PMC *src)
241{
242#line 162 "./src/pmc/continuation.pmc"
243
244    Parrot_Continuation_attributes * const cc_self = PARROT_CONTINUATION(pmc);
245    Parrot_Continuation_attributes * const cc_src  = PARROT_CONTINUATION(src);
246
247    STRUCT_COPY(cc_self, cc_src);
248#line 248 "./src/pmc/continuation.c"
249}
250static  void 
251Parrot_Continuation_set_pointer(PARROT_INTERP, PMC *pmc, void *value)
252{
253#line 179 "./src/pmc/continuation.pmc"
254
255    opcode_t                       * const pos = (opcode_t *)value;
256    Parrot_Continuation_attributes * const cc  = PARROT_CONTINUATION(pmc);
257
258    cc->address    = pos;
259    cc->runloop_id = interp->current_runloop_id;
260#line 260 "./src/pmc/continuation.c"
261}
262static  void
263Parrot_Continuation_nci_caller(PARROT_INTERP, PMC *pmc)
264{
265#line 423 "/Users/baest/programming/parrot/tools/build/../../lib/Parrot/Pmc2c/PCCMETHOD.pm"
266    PMC * const _ctx         = CURRENT_CONTEXT(interp);
267    PMC * const _ccont       = Parrot_pcc_get_continuation(interp, _ctx);
268    PMC * const _call_object = Parrot_pcc_get_signature(interp, _ctx);
269
270    Parrot_pcc_set_signature(interp, _ctx, NULL);
271
272    { /* BEGIN PARMS SCOPE */
273#line 273 "./src/pmc/continuation.pmc"
274PMC* pmc;
275
276#line 431 "/Users/baest/programming/parrot/tools/build/../../lib/Parrot/Pmc2c/PCCMETHOD.pm"
277        Parrot_pcc_fill_params_from_c_args(interp, _call_object, "Pi",
278            &pmc);
279#line 435 "/Users/baest/programming/parrot/tools/build/../../lib/Parrot/Pmc2c/PCCMETHOD.pm"
280    { /* BEGIN PMETHOD BODY */
281#line 291 "./src/pmc/continuation.pmc"
282
283    Parrot_Continuation_attributes * const cc = PARROT_CONTINUATION(pmc);
284    PMC *caller = Parrot_pcc_get_sub(interp, cc->to_ctx);
285
286    if (!caller)
287        caller = PMCNULL;
288    else {
289        Parrot_Sub_attributes *sub;
290        PMC_get_sub(interp, caller, sub);
291        if (!sub->seg)
292            caller = PMCNULL;
293    }
294
295    #line 260 "/Users/baest/programming/parrot/tools/build/../../lib/Parrot/Pmc2c/PCCMETHOD.pm"
296    {
297    /*BEGIN RETURN PMC *caller */
298#line 267 "/Users/baest/programming/parrot/tools/build/../../lib/Parrot/Pmc2c/PCCMETHOD.pm"
299    Parrot_pcc_fill_returns_from_c_args(interp, _call_object, "P",
300            (PMC*)caller);
301    return;
302    /*END RETURN PMC *caller */
303    }
304#line 304 "./src/pmc/continuation.pmc"
305
306
307#line 443 "/Users/baest/programming/parrot/tools/build/../../lib/Parrot/Pmc2c/PCCMETHOD.pm"
308
309    } /* END PMETHOD BODY */
310    } /* END PARAMS SCOPE */
311  no_return:
312    return;
313#line 313 "./src/pmc/continuation.c"
314}
315static  void
316Parrot_Continuation_nci_continuation(PARROT_INTERP, PMC *pmc)
317{
318#line 423 "/Users/baest/programming/parrot/tools/build/../../lib/Parrot/Pmc2c/PCCMETHOD.pm"
319    PMC * const _ctx         = CURRENT_CONTEXT(interp);
320    PMC * const _ccont       = Parrot_pcc_get_continuation(interp, _ctx);
321    PMC * const _call_object = Parrot_pcc_get_signature(interp, _ctx);
322
323    Parrot_pcc_set_signature(interp, _ctx, NULL);
324
325    { /* BEGIN PARMS SCOPE */
326#line 326 "./src/pmc/continuation.pmc"
327PMC* pmc;
328
329#line 431 "/Users/baest/programming/parrot/tools/build/../../lib/Parrot/Pmc2c/PCCMETHOD.pm"
330        Parrot_pcc_fill_params_from_c_args(interp, _call_object, "Pi",
331            &pmc);
332#line 435 "/Users/baest/programming/parrot/tools/build/../../lib/Parrot/Pmc2c/PCCMETHOD.pm"
333    { /* BEGIN PMETHOD BODY */
334#line 317 "./src/pmc/continuation.pmc"
335
336    Parrot_Continuation_attributes * const cc = PARROT_CONTINUATION(pmc);
337    PMC * const cont = Parrot_pcc_get_continuation(interp, cc->to_ctx);
338
339    if (cont)
340        #line 260 "/Users/baest/programming/parrot/tools/build/../../lib/Parrot/Pmc2c/PCCMETHOD.pm"
341    {
342    /*BEGIN RETURN PMC *cont */
343#line 267 "/Users/baest/programming/parrot/tools/build/../../lib/Parrot/Pmc2c/PCCMETHOD.pm"
344    Parrot_pcc_fill_returns_from_c_args(interp, _call_object, "P",
345            (PMC*)cont);
346    return;
347    /*END RETURN PMC *cont */
348    }
349#line 322 "./src/pmc/continuation.pmc"
350
351
352    #line 260 "/Users/baest/programming/parrot/tools/build/../../lib/Parrot/Pmc2c/PCCMETHOD.pm"
353    {
354    /*BEGIN RETURN PMC *PMCNULL */
355#line 267 "/Users/baest/programming/parrot/tools/build/../../lib/Parrot/Pmc2c/PCCMETHOD.pm"
356    Parrot_pcc_fill_returns_from_c_args(interp, _call_object, "P",
357            (PMC*)PMCNULL);
358    return;
359    /*END RETURN PMC *PMCNULL */
360    }
361#line 324 "./src/pmc/continuation.pmc"
362
363#line 443 "/Users/baest/programming/parrot/tools/build/../../lib/Parrot/Pmc2c/PCCMETHOD.pm"
364
365    } /* END PMETHOD BODY */
366    } /* END PARAMS SCOPE */
367  no_return:
368    return;
369#line 369 "./src/pmc/continuation.c"
370}
371#include "pmc/pmc_default.h"
372
373PARROT_EXPORT
374VTABLE *Parrot_Continuation_update_vtable(VTABLE *vt) {
375    vt->clone = Parrot_Continuation_clone;
376    vt->defined = Parrot_Continuation_defined;
377    vt->get_bool = Parrot_Continuation_get_bool;
378    vt->get_pointer = Parrot_Continuation_get_pointer;
379    vt->get_string = Parrot_Continuation_get_string;
380    vt->init = Parrot_Continuation_init;
381    vt->init_pmc = Parrot_Continuation_init_pmc;
382    vt->invoke = Parrot_Continuation_invoke;
383    vt->mark = Parrot_Continuation_mark;
384    vt->set_pmc = Parrot_Continuation_set_pmc;
385    vt->set_pointer = Parrot_Continuation_set_pointer;
386    vt->attr_size = sizeof(Parrot_Continuation_attributes);
387
388    return vt;
389}
390
391
392PARROT_EXPORT
393VTABLE *Parrot_Continuation_ro_update_vtable(ARGMOD(VTABLE *vt)) {
394    vt->clone = Parrot_Continuation_clone;
395    vt->defined = Parrot_Continuation_defined;
396    vt->get_bool = Parrot_Continuation_get_bool;
397    vt->get_pointer = Parrot_Continuation_get_pointer;
398    vt->get_string = Parrot_Continuation_get_string;
399    vt->init = Parrot_Continuation_init;
400    vt->init_pmc = Parrot_Continuation_init_pmc;
401    vt->invoke = Parrot_Continuation_invoke;
402    vt->mark = Parrot_Continuation_mark;
403    vt->attr_size = sizeof(Parrot_Continuation_attributes);
404
405    return vt;
406}
407
408PARROT_EXPORT
409PARROT_CANNOT_RETURN_NULL
410PARROT_WARN_UNUSED_RESULT
411VTABLE* Parrot_Continuation_get_vtable(PARROT_INTERP) {
412    VTABLE *vt;
413    vt = Parrot_default_get_vtable(interp);
414    Parrot_Continuation_update_vtable(vt);
415
416    return vt;
417}
418
419PARROT_EXPORT
420PARROT_CANNOT_RETURN_NULL
421PARROT_WARN_UNUSED_RESULT
422VTABLE* Parrot_Continuation_ro_get_vtable(PARROT_INTERP) {
423    VTABLE *vt;
424    vt = Parrot_default_ro_get_vtable(interp);
425    Parrot_Continuation_ro_update_vtable(vt);
426
427    return vt;
428}
429
430PARROT_EXPORT
431PARROT_CANNOT_RETURN_NULL
432PARROT_WARN_UNUSED_RESULT
433PMC* Parrot_Continuation_get_mro(PARROT_INTERP, PMC* mro) {
434    if (PMC_IS_NULL(mro)) {
435        mro = pmc_new(interp, enum_class_ResizableStringArray);
436    }
437
438    VTABLE_unshift_string(interp, mro,
439        string_make(interp, "Continuation", 12, NULL, 0));
440    return mro;
441}
442
443PARROT_EXPORT
444PARROT_CANNOT_RETURN_NULL
445PARROT_WARN_UNUSED_RESULT
446Hash* Parrot_Continuation_get_isa(PARROT_INTERP, Hash* isa) {
447    if (isa == NULL) {
448        isa = parrot_new_hash(interp);
449    }
450
451    parrot_hash_put(interp, isa, (void *)(CONST_STRING_GEN(interp, "Continuation")), PMCNULL);
452    return isa;
453}
454
455void
456Parrot_Continuation_class_init(PARROT_INTERP, int entry, int pass)
457{
458    static const char attr_defs [] =
459        ":seg :address Fto_ctx Fto_call_object Ffrom_ctx :runloop_id :invoked ";
460    if (pass == 0) {
461        VTABLE * const vt  = Parrot_Continuation_get_vtable(interp);
462        vt->base_type      = enum_class_Continuation;
463        vt->flags          = 0|VTABLE_HAS_READONLY_FLAG;
464        vt->attribute_defs = attr_defs;
465        interp->vtables[entry] = vt;
466
467        vt->whoami       = CONST_STRING_GEN(interp, "Continuation");
468        vt->provides_str = CONST_STRING_GEN(interp, "scalar");
469        vt->isa_hash     = NULL;
470        {
471            VTABLE                   *vt_ro;
472            vt_ro                 = Parrot_Continuation_ro_get_vtable(interp);
473            vt_ro->base_type      = enum_class_Continuation;
474            vt_ro->flags          = 0|VTABLE_IS_READONLY_FLAG;
475
476            vt_ro->attribute_defs = attr_defs;
477
478            vt_ro->base_type           = entry;
479            vt_ro->whoami              = vt->whoami;
480            vt_ro->provides_str        = vt->provides_str;
481            vt->ro_variant_vtable      = vt_ro;
482            vt_ro->ro_variant_vtable = vt;
483            vt_ro->isa_hash            = vt->isa_hash;
484        }
485
486    }
487    else { /* pass */
488        {
489            VTABLE * const vt  = interp->vtables[entry];
490
491            vt->mro = Parrot_Continuation_get_mro(interp, PMCNULL);
492
493            if (vt->ro_variant_vtable)
494                vt->ro_variant_vtable->mro = vt->mro;
495        }
496
497        /* set up MRO and _namespace */
498        Parrot_create_mro(interp, entry);
499        register_raw_nci_method_in_ns(interp, entry, F2DPTR(Parrot_Continuation_nci_caller), CONST_STRING_GEN(interp, "caller"));
500        register_raw_nci_method_in_ns(interp, entry, F2DPTR(Parrot_Continuation_nci_continuation), CONST_STRING_GEN(interp, "continuation"));
501        {
502        }
503    } /* pass */
504} /* Parrot_Continuation_class_init */
505#line 325 "./src/pmc/continuation.pmc"
506
507
508/*
509
510=back
511
512=head1 HISTORY
513
514Initial revision by sean 2002/08/04.
515
516=cut
517
518*/
519
520/*
521 * Local variables:
522 *   c-file-style: "parrot"
523 * End:
524 * vim: expandtab shiftwidth=4:
525 */