|
|
1 | #define CORO_CLONE 1 //D |
|
|
2 | |
1 | #include "libcoro/coro.c" |
3 | #include "libcoro/coro.c" |
2 | |
4 | |
3 | #define PERL_NO_GET_CONTEXT |
5 | #define PERL_NO_GET_CONTEXT |
4 | #define PERL_EXT |
6 | #define PERL_EXT |
5 | |
7 | |
… | |
… | |
101 | # define CvISXSUB_on(cv) (void)cv |
103 | # define CvISXSUB_on(cv) (void)cv |
102 | #endif |
104 | #endif |
103 | #ifndef CvISXSUB |
105 | #ifndef CvISXSUB |
104 | # define CvISXSUB(cv) (CvXSUB (cv) ? TRUE : FALSE) |
106 | # define CvISXSUB(cv) (CvXSUB (cv) ? TRUE : FALSE) |
105 | #endif |
107 | #endif |
|
|
108 | #ifndef Newx |
|
|
109 | # define Newx(ptr,nitems,type) New (0,ptr,nitems,type) |
|
|
110 | #endif |
106 | |
111 | |
107 | /* 5.8.7 */ |
112 | /* 5.8.7 */ |
108 | #ifndef SvRV_set |
113 | #ifndef SvRV_set |
109 | # define SvRV_set(s,v) SvRV(s) = (v) |
114 | # define SvRV_set(s,v) SvRV(s) = (v) |
110 | #endif |
115 | #endif |
… | |
… | |
347 | GV *gvp; |
352 | GV *gvp; |
348 | return sv_2cv (sv, &st, &gvp, 0); |
353 | return sv_2cv (sv, &st, &gvp, 0); |
349 | } |
354 | } |
350 | |
355 | |
351 | static AV * |
356 | static AV * |
352 | coro_clone_padlist (pTHX_ CV *cv) |
357 | coro_derive_padlist (pTHX_ CV *cv) |
353 | { |
358 | { |
354 | AV *padlist = CvPADLIST (cv); |
359 | AV *padlist = CvPADLIST (cv); |
355 | AV *newpadlist, *newpad; |
360 | AV *newpadlist, *newpad; |
356 | |
361 | |
357 | newpadlist = newAV (); |
362 | newpadlist = newAV (); |
… | |
… | |
477 | CV *cp = Perl_cv_clone (aTHX_ cv); |
482 | CV *cp = Perl_cv_clone (aTHX_ cv); |
478 | CvPADLIST (cv) = CvPADLIST (cp); |
483 | CvPADLIST (cv) = CvPADLIST (cp); |
479 | CvPADLIST (cp) = 0; |
484 | CvPADLIST (cp) = 0; |
480 | SvREFCNT_dec (cp); |
485 | SvREFCNT_dec (cp); |
481 | #else |
486 | #else |
482 | CvPADLIST (cv) = coro_clone_padlist (aTHX_ cv); |
487 | CvPADLIST (cv) = coro_derive_padlist (aTHX_ cv); |
483 | #endif |
488 | #endif |
484 | } |
489 | } |
485 | } |
490 | } |
486 | |
491 | |
487 | static void |
492 | static void |
… | |
… | |
901 | slf_frame.prepare = prepare_nop; /* provide a nop function for an eventual pp_slf */ |
906 | slf_frame.prepare = prepare_nop; /* provide a nop function for an eventual pp_slf */ |
902 | slf_frame.check = slf_check_nop; /* signal pp_slf to not repeat */ |
907 | slf_frame.check = slf_check_nop; /* signal pp_slf to not repeat */ |
903 | |
908 | |
904 | /* and we have to provide the pp_slf op in any case, so pp_slf can skip it */ |
909 | /* and we have to provide the pp_slf op in any case, so pp_slf can skip it */ |
905 | coro_setup_op.op_next = PL_op; |
910 | coro_setup_op.op_next = PL_op; |
906 | coro_setup_op.op_type = OP_CUSTOM; |
911 | coro_setup_op.op_type = OP_ENTERSUB; |
907 | coro_setup_op.op_ppaddr = pp_slf; |
912 | coro_setup_op.op_ppaddr = pp_slf; |
908 | /* no flags etc. required, as an init function won't be called */ |
913 | /* no flags etc. required, as an init function won't be called */ |
909 | |
914 | |
910 | PL_op = (OP *)&coro_setup_op; |
915 | PL_op = (OP *)&coro_setup_op; |
911 | |
916 | |
… | |
… | |
1026 | { |
1031 | { |
1027 | PERL_CONTEXT *cx = &cxstack[cxstack_ix]; |
1032 | PERL_CONTEXT *cx = &cxstack[cxstack_ix]; |
1028 | |
1033 | |
1029 | if (CxTYPE (cx) == CXt_SUB && oldcxix < cxstack_ix) |
1034 | if (CxTYPE (cx) == CXt_SUB && oldcxix < cxstack_ix) |
1030 | { |
1035 | { |
1031 | runops_proc_t old_runops = PL_runops; |
|
|
1032 | dSP; |
1036 | dSP; |
1033 | GV *gv = CvGV (cx->blk_sub.cv); |
1037 | GV *gv = CvGV (cx->blk_sub.cv); |
1034 | SV *fullname = sv_2mortal (newSV (0)); |
1038 | SV *fullname = sv_2mortal (newSV (0)); |
1035 | |
1039 | |
1036 | if (isGV (gv)) |
1040 | if (isGV (gv)) |
… | |
… | |
1657 | else |
1661 | else |
1658 | { |
1662 | { |
1659 | next->flags &= ~CF_READY; |
1663 | next->flags &= ~CF_READY; |
1660 | --coro_nready; |
1664 | --coro_nready; |
1661 | |
1665 | |
1662 | return prepare_schedule_to (aTHX_ ta, next); |
1666 | prepare_schedule_to (aTHX_ ta, next); |
|
|
1667 | break; |
1663 | } |
1668 | } |
1664 | } |
1669 | } |
1665 | else |
1670 | else |
1666 | { |
1671 | { |
1667 | /* nothing to schedule: call the idle handler */ |
1672 | /* nothing to schedule: call the idle handler */ |
… | |
… | |
2250 | } |
2255 | } |
2251 | else |
2256 | else |
2252 | slf_argc = 0; |
2257 | slf_argc = 0; |
2253 | |
2258 | |
2254 | PL_op->op_ppaddr = pp_slf; |
2259 | PL_op->op_ppaddr = pp_slf; |
2255 | PL_op->op_type = OP_CUSTOM; /* maybe we should leave it at entersub? */ |
2260 | /*PL_op->op_type = OP_CUSTOM; /* we do behave like entersub still */ |
2256 | |
2261 | |
2257 | PL_op = (OP *)&slf_restore; |
2262 | PL_op = (OP *)&slf_restore; |
2258 | } |
2263 | } |
2259 | |
2264 | |
2260 | /*****************************************************************************/ |
2265 | /*****************************************************************************/ |
… | |
… | |
2724 | XSRETURN_EMPTY; |
2729 | XSRETURN_EMPTY; |
2725 | } |
2730 | } |
2726 | |
2731 | |
2727 | /*****************************************************************************/ |
2732 | /*****************************************************************************/ |
2728 | |
2733 | |
|
|
2734 | #if CORO_CLONE |
|
|
2735 | # include "clone.c" |
|
|
2736 | #endif |
|
|
2737 | |
2729 | MODULE = Coro::State PACKAGE = Coro::State PREFIX = api_ |
2738 | MODULE = Coro::State PACKAGE = Coro::State PREFIX = api_ |
2730 | |
2739 | |
2731 | PROTOTYPES: DISABLE |
2740 | PROTOTYPES: DISABLE |
2732 | |
2741 | |
2733 | BOOT: |
2742 | BOOT: |
… | |
… | |
2765 | |
2774 | |
2766 | { |
2775 | { |
2767 | SV *slf = sv_2mortal (newSViv (PTR2IV (pp_slf))); |
2776 | SV *slf = sv_2mortal (newSViv (PTR2IV (pp_slf))); |
2768 | |
2777 | |
2769 | if (!PL_custom_op_names) PL_custom_op_names = newHV (); |
2778 | if (!PL_custom_op_names) PL_custom_op_names = newHV (); |
2770 | hv_store_ent (PL_custom_op_names, slf, |
2779 | hv_store_ent (PL_custom_op_names, slf, newSVpv ("coro_slf", 0), 0); |
2771 | newSVpv ("coro_slf", 0), 0); |
|
|
2772 | |
2780 | |
2773 | if (!PL_custom_op_descs) PL_custom_op_descs = newHV (); |
2781 | if (!PL_custom_op_descs) PL_custom_op_descs = newHV (); |
2774 | hv_store_ent (PL_custom_op_descs, slf, |
2782 | hv_store_ent (PL_custom_op_descs, slf, newSVpv ("coro schedule like function", 0), 0); |
2775 | newSVpv ("coro schedule like function", 0), 0); |
|
|
2776 | } |
2783 | } |
2777 | |
2784 | |
2778 | coroapi.ver = CORO_API_VERSION; |
2785 | coroapi.ver = CORO_API_VERSION; |
2779 | coroapi.rev = CORO_API_REVISION; |
2786 | coroapi.rev = CORO_API_REVISION; |
2780 | |
2787 | |
… | |
… | |
2873 | void |
2880 | void |
2874 | _exit (int code) |
2881 | _exit (int code) |
2875 | PROTOTYPE: $ |
2882 | PROTOTYPE: $ |
2876 | CODE: |
2883 | CODE: |
2877 | _exit (code); |
2884 | _exit (code); |
|
|
2885 | |
|
|
2886 | #if CORO_CLONE |
|
|
2887 | |
|
|
2888 | SV * |
|
|
2889 | clone (Coro::State coro) |
|
|
2890 | CODE: |
|
|
2891 | { |
|
|
2892 | struct coro *ncoro = coro_clone (coro); |
|
|
2893 | MAGIC *mg; |
|
|
2894 | /* TODO: too much duplication */ |
|
|
2895 | ncoro->hv = newHV (); |
|
|
2896 | mg = sv_magicext ((SV *)ncoro->hv, 0, CORO_MAGIC_type_state, &coro_state_vtbl, (char *)ncoro, 0); |
|
|
2897 | mg->mg_flags |= MGf_DUP; |
|
|
2898 | RETVAL = sv_bless (newRV_noinc ((SV *)ncoro->hv), SvSTASH (coro->hv)); |
|
|
2899 | } |
|
|
2900 | OUTPUT: |
|
|
2901 | RETVAL |
|
|
2902 | |
|
|
2903 | #endif |
2878 | |
2904 | |
2879 | int |
2905 | int |
2880 | cctx_stacksize (int new_stacksize = 0) |
2906 | cctx_stacksize (int new_stacksize = 0) |
2881 | PROTOTYPE: ;$ |
2907 | PROTOTYPE: ;$ |
2882 | CODE: |
2908 | CODE: |