… | |
… | |
252 | #undef VAR |
252 | #undef VAR |
253 | } perl_slots; |
253 | } perl_slots; |
254 | |
254 | |
255 | #define SLOT_COUNT ((sizeof (perl_slots) + sizeof (PERL_CONTEXT) - 1) / sizeof (PERL_CONTEXT)) |
255 | #define SLOT_COUNT ((sizeof (perl_slots) + sizeof (PERL_CONTEXT) - 1) / sizeof (PERL_CONTEXT)) |
256 | |
256 | |
257 | /* this is the per-perl-coro slf frame info */ |
|
|
258 | /* it is treated like other "global" interpreter data */ |
|
|
259 | /* and unfortunately is copied around, so kepe it small */ |
|
|
260 | struct slf_frame |
|
|
261 | { |
|
|
262 | void (*prepare) (struct coro_transfer_args *ta); /* 0 means not yet initialised */ |
|
|
263 | int (*check) (pTHX); |
|
|
264 | }; |
|
|
265 | |
|
|
266 | /* this is a structure representing a perl-level coroutine */ |
257 | /* this is a structure representing a perl-level coroutine */ |
267 | struct coro { |
258 | struct coro { |
268 | /* the C coroutine allocated to this perl coroutine, if any */ |
259 | /* the C coroutine allocated to this perl coroutine, if any */ |
269 | coro_cctx *cctx; |
260 | coro_cctx *cctx; |
270 | |
261 | |
271 | /* process data */ |
262 | /* process data */ |
272 | struct slf_frame slf_frame; /* saved slf frame */ |
263 | struct CoroSLF slf_frame; /* saved slf frame */ |
273 | void *slf_data; |
|
|
274 | AV *mainstack; |
264 | AV *mainstack; |
275 | perl_slots *slot; /* basically the saved sp */ |
265 | perl_slots *slot; /* basically the saved sp */ |
276 | |
266 | |
277 | AV *args; /* data associated with this coroutine (initial args) */ |
267 | AV *args; /* data associated with this coroutine (initial args) */ |
278 | int refcnt; /* coroutines are refcounted, yes */ |
268 | int refcnt; /* coroutines are refcounted, yes */ |
… | |
… | |
294 | }; |
284 | }; |
295 | |
285 | |
296 | typedef struct coro *Coro__State; |
286 | typedef struct coro *Coro__State; |
297 | typedef struct coro *Coro__State_or_hashref; |
287 | typedef struct coro *Coro__State_or_hashref; |
298 | |
288 | |
299 | static struct slf_frame slf_frame; /* the current slf frame */ |
289 | static struct CoroSLF slf_frame; /* the current slf frame */ |
300 | |
290 | |
301 | /** Coro ********************************************************************/ |
291 | /** Coro ********************************************************************/ |
302 | |
292 | |
303 | #define PRIO_MAX 3 |
293 | #define PRIO_MAX 3 |
304 | #define PRIO_HIGH 1 |
294 | #define PRIO_HIGH 1 |
… | |
… | |
526 | |
516 | |
527 | PUTBACK; |
517 | PUTBACK; |
528 | } |
518 | } |
529 | |
519 | |
530 | slf_frame = c->slf_frame; |
520 | slf_frame = c->slf_frame; |
531 | coroapi.slf_data = c->slf_data; |
|
|
532 | } |
521 | } |
533 | |
522 | |
534 | static void |
523 | static void |
535 | save_perl (pTHX_ Coro__State c) |
524 | save_perl (pTHX_ Coro__State c) |
536 | { |
525 | { |
537 | c->slf_data = coroapi.slf_data; |
|
|
538 | c->slf_frame = slf_frame; |
526 | c->slf_frame = slf_frame; |
539 | |
527 | |
540 | { |
528 | { |
541 | dSP; |
529 | dSP; |
542 | I32 cxix = cxstack_ix; |
530 | I32 cxix = cxstack_ix; |
… | |
… | |
1308 | transfer_check (pTHX_ struct coro *prev, struct coro *next) |
1296 | transfer_check (pTHX_ struct coro *prev, struct coro *next) |
1309 | { |
1297 | { |
1310 | if (expect_true (prev != next)) |
1298 | if (expect_true (prev != next)) |
1311 | { |
1299 | { |
1312 | if (expect_false (!(prev->flags & (CF_RUNNING | CF_NEW)))) |
1300 | if (expect_false (!(prev->flags & (CF_RUNNING | CF_NEW)))) |
1313 | croak ("Coro::State::transfer called with non-running/new prev Coro::State, but can only transfer from running or new states"); |
1301 | croak ("Coro::State::transfer called with non-running/new prev Coro::State, but can only transfer from running or new states,"); |
1314 | |
1302 | |
1315 | if (expect_false (next->flags & CF_RUNNING)) |
1303 | if (expect_false (next->flags & CF_RUNNING)) |
1316 | croak ("Coro::State::transfer called with running next Coro::State, but can only transfer to inactive states"); |
1304 | croak ("Coro::State::transfer called with running next Coro::State, but can only transfer to inactive states,"); |
1317 | |
1305 | |
1318 | if (expect_false (next->flags & CF_DESTROYED)) |
1306 | if (expect_false (next->flags & CF_DESTROYED)) |
1319 | croak ("Coro::State::transfer called with destroyed next Coro::State, but can only transfer to inactive states"); |
1307 | croak ("Coro::State::transfer called with destroyed next Coro::State, but can only transfer to inactive states,"); |
1320 | |
1308 | |
1321 | #if !PERL_VERSION_ATLEAST (5,10,0) |
1309 | #if !PERL_VERSION_ATLEAST (5,10,0) |
1322 | if (expect_false (PL_lex_state != LEX_NOTPARSING)) |
1310 | if (expect_false (PL_lex_state != LEX_NOTPARSING)) |
1323 | croak ("Coro::State::transfer called while parsing, but this is not supported in your perl version"); |
1311 | croak ("Coro::State::transfer called while parsing, but this is not supported in your perl version,"); |
1324 | #endif |
1312 | #endif |
1325 | } |
1313 | } |
1326 | } |
1314 | } |
1327 | |
1315 | |
1328 | /* always use the TRANSFER macro */ |
1316 | /* always use the TRANSFER macro */ |
… | |
… | |
1435 | |
1423 | |
1436 | if (coro->mainstack && coro->mainstack != main_mainstack) |
1424 | if (coro->mainstack && coro->mainstack != main_mainstack) |
1437 | { |
1425 | { |
1438 | struct coro temp; |
1426 | struct coro temp; |
1439 | |
1427 | |
1440 | if (coro->flags & CF_RUNNING) |
1428 | assert (("FATAL: tried to destroy currently running coroutine (please report)", !(coro->flags & CF_RUNNING))); |
1441 | croak ("FATAL: tried to destroy currently running coroutine"); |
|
|
1442 | |
1429 | |
1443 | save_perl (aTHX_ &temp); |
1430 | save_perl (aTHX_ &temp); |
1444 | load_perl (aTHX_ coro); |
1431 | load_perl (aTHX_ coro); |
1445 | |
1432 | |
1446 | coro_destruct (aTHX_ coro); |
1433 | coro_destruct (aTHX_ coro); |
… | |
… | |
1718 | if (flags & CC_TRACE) |
1705 | if (flags & CC_TRACE) |
1719 | { |
1706 | { |
1720 | if (!coro->cctx) |
1707 | if (!coro->cctx) |
1721 | coro->cctx = cctx_new_run (); |
1708 | coro->cctx = cctx_new_run (); |
1722 | else if (!(coro->cctx->flags & CC_TRACE)) |
1709 | else if (!(coro->cctx->flags & CC_TRACE)) |
1723 | croak ("cannot enable tracing on coroutine with custom stack"); |
1710 | croak ("cannot enable tracing on coroutine with custom stack,"); |
1724 | |
1711 | |
1725 | coro->cctx->flags |= CC_NOREUSE | (flags & (CC_TRACE | CC_TRACE_ALL)); |
1712 | coro->cctx->flags |= CC_NOREUSE | (flags & (CC_TRACE | CC_TRACE_ALL)); |
1726 | } |
1713 | } |
1727 | else if (coro->cctx && coro->cctx->flags & CC_TRACE) |
1714 | else if (coro->cctx && coro->cctx->flags & CC_TRACE) |
1728 | { |
1715 | { |
… | |
… | |
1833 | static const CV *slf_cv; /* for quick consistency check */ |
1820 | static const CV *slf_cv; /* for quick consistency check */ |
1834 | |
1821 | |
1835 | static UNOP slf_restore; /* restore stack as entersub did, for first-re-run */ |
1822 | static UNOP slf_restore; /* restore stack as entersub did, for first-re-run */ |
1836 | static SV *slf_arg0; |
1823 | static SV *slf_arg0; |
1837 | static SV *slf_arg1; |
1824 | static SV *slf_arg1; |
|
|
1825 | static SV *slf_arg2; |
1838 | |
1826 | |
1839 | /* this restores the stack in the case we patched the entersub, to */ |
1827 | /* this restores the stack in the case we patched the entersub, to */ |
1840 | /* recreate the stack frame as perl will on following calls */ |
1828 | /* recreate the stack frame as perl will on following calls */ |
1841 | /* since entersub cleared the stack */ |
1829 | /* since entersub cleared the stack */ |
1842 | static OP * |
1830 | static OP * |
… | |
… | |
1847 | PUSHMARK (SP); |
1835 | PUSHMARK (SP); |
1848 | |
1836 | |
1849 | EXTEND (SP, 3); |
1837 | EXTEND (SP, 3); |
1850 | if (slf_arg0) PUSHs (sv_2mortal (slf_arg0)); |
1838 | if (slf_arg0) PUSHs (sv_2mortal (slf_arg0)); |
1851 | if (slf_arg1) PUSHs (sv_2mortal (slf_arg1)); |
1839 | if (slf_arg1) PUSHs (sv_2mortal (slf_arg1)); |
|
|
1840 | if (slf_arg2) PUSHs (sv_2mortal (slf_arg2)); |
1852 | PUSHs ((SV *)CvGV (slf_cv)); |
1841 | PUSHs ((SV *)CvGV (slf_cv)); |
1853 | |
1842 | |
1854 | RETURNOP (slf_restore.op_first); |
1843 | RETURNOP (slf_restore.op_first); |
1855 | } |
1844 | } |
1856 | |
1845 | |
1857 | static void |
1846 | static void |
|
|
1847 | slf_prepare_set_stacklevel (pTHX_ struct coro_transfer_args *ta) |
|
|
1848 | { |
|
|
1849 | prepare_set_stacklevel (ta, (struct coro_cctx *)slf_frame.data); |
|
|
1850 | } |
|
|
1851 | |
|
|
1852 | static void |
1858 | slf_init_set_stacklevel (pTHX_ SV **arg, int items) |
1853 | slf_init_set_stacklevel (pTHX_ struct CoroSLF *frame, SV **arg, int items) |
1859 | { |
1854 | { |
1860 | assert (("FATAL: set_stacklevel needs the coro cctx as sole argument", items == 1)); |
1855 | assert (("FATAL: set_stacklevel needs the coro cctx as sole argument", items == 1)); |
1861 | CORO_SLF_DATA = (void *)SvIV (arg [0]); |
|
|
1862 | } |
|
|
1863 | |
1856 | |
|
|
1857 | frame->prepare = slf_prepare_set_stacklevel; |
|
|
1858 | frame->check = slf_check_nop; |
|
|
1859 | frame->data = (void *)SvIV (arg [0]); |
|
|
1860 | } |
|
|
1861 | |
1864 | static void |
1862 | static void |
1865 | slf_prepare_set_stacklevel (pTHX_ struct coro_transfer_args *ta) |
1863 | slf_prepare_transfer (pTHX_ struct coro_transfer_args *ta) |
1866 | { |
1864 | { |
1867 | prepare_set_stacklevel (ta, (struct coro_cctx *)CORO_SLF_DATA); |
1865 | SV **arg = (SV **)slf_frame.data; |
1868 | } |
|
|
1869 | |
1866 | |
|
|
1867 | prepare_transfer (ta, arg [0], arg [1]); |
|
|
1868 | } |
|
|
1869 | |
1870 | static void |
1870 | static void |
1871 | slf_init_transfer (pTHX_ SV **arg, int items) |
1871 | slf_init_transfer (pTHX_ struct CoroSLF *frame, SV **arg, int items) |
1872 | { |
1872 | { |
1873 | if (items != 2) |
1873 | if (items != 2) |
1874 | croak ("Coro::State::transfer (prev, next) expects two arguments, not %d.", items); |
1874 | croak ("Coro::State::transfer (prev, next) expects two arguments, not %d,", items); |
1875 | |
1875 | |
|
|
1876 | frame->prepare = slf_prepare_transfer; |
|
|
1877 | frame->check = slf_check_nop; |
1876 | CORO_SLF_DATA = (void *)arg; /* let's hope it will stay valid */ |
1878 | frame->data = (void *)arg; /* let's hope it will stay valid */ |
1877 | } |
1879 | } |
1878 | |
1880 | |
1879 | static void |
1881 | static void |
1880 | slf_prepare_transfer (pTHX_ struct coro_transfer_args *ta) |
1882 | slf_init_schedule (pTHX_ struct CoroSLF *frame, SV **arg, int items) |
1881 | { |
1883 | { |
1882 | SV **arg = (SV **)CORO_SLF_DATA; |
1884 | frame->prepare = prepare_schedule; |
1883 | |
1885 | frame->check = slf_check_nop; |
1884 | prepare_transfer (ta, arg [0], arg [1]); |
|
|
1885 | } |
1886 | } |
1886 | |
1887 | |
1887 | static void |
1888 | static void |
1888 | slf_init_nop (pTHX_ SV **arg, int items) |
1889 | slf_init_cede (pTHX_ struct CoroSLF *frame, SV **arg, int items) |
1889 | { |
1890 | { |
|
|
1891 | frame->prepare = prepare_cede; |
|
|
1892 | frame->check = slf_check_nop; |
1890 | } |
1893 | } |
1891 | |
1894 | |
1892 | /* slf_prepare_schedule == prepare_schedule */ |
1895 | static void |
1893 | /* slf_prepare_cede == prepare_cede */ |
1896 | slf_init_cede_notself (pTHX_ struct CoroSLF *frame, SV **arg, int items) |
1894 | /* slf_prepare_notself == prepare_notself */ |
1897 | { |
|
|
1898 | frame->prepare = prepare_cede_notself; |
|
|
1899 | frame->check = slf_check_nop; |
|
|
1900 | } |
1895 | |
1901 | |
1896 | /* we hijack an hopefully unused CV flag for our purposes */ |
1902 | /* we hijack an hopefully unused CV flag for our purposes */ |
1897 | #define CVf_SLF 0x4000 |
1903 | #define CVf_SLF 0x4000 |
1898 | |
1904 | |
1899 | /* |
1905 | /* |
… | |
… | |
1905 | static OP * |
1911 | static OP * |
1906 | pp_slf (pTHX) |
1912 | pp_slf (pTHX) |
1907 | { |
1913 | { |
1908 | I32 checkmark; /* mark SP to see how many elements check has pushed */ |
1914 | I32 checkmark; /* mark SP to see how many elements check has pushed */ |
1909 | |
1915 | |
|
|
1916 | /* set up the slf frame, unless it has already been set-up */ |
|
|
1917 | /* the latter happens when a new coro has been started */ |
|
|
1918 | /* or when a new cctx was attached to an existing coroutine */ |
1910 | if (expect_true (!slf_frame.prepare)) |
1919 | if (expect_true (!slf_frame.prepare)) |
1911 | { |
1920 | { |
1912 | /* first iteration */ |
1921 | /* first iteration */ |
1913 | dSP; |
1922 | dSP; |
1914 | SV **arg = PL_stack_base + TOPMARK + 1; |
1923 | SV **arg = PL_stack_base + TOPMARK + 1; |
1915 | int items = SP - arg; /* args without function object */ |
1924 | int items = SP - arg; /* args without function object */ |
1916 | SV *gv = *sp; |
1925 | SV *gv = *sp; |
1917 | struct CoroSLF *slf; |
|
|
1918 | |
1926 | |
1919 | /* do a quick consistency check on the "function" object, and if it isn't */ |
1927 | /* do a quick consistency check on the "function" object, and if it isn't */ |
1920 | /* for us, divert to the real entersub */ |
1928 | /* for us, divert to the real entersub */ |
1921 | if (SvTYPE (gv) != SVt_PVGV || !(CvFLAGS (GvCV (gv)) & CVf_SLF)) |
1929 | if (SvTYPE (gv) != SVt_PVGV || !(CvFLAGS (GvCV (gv)) & CVf_SLF)) |
1922 | return PL_ppaddr[OP_ENTERSUB](aTHX); |
1930 | return PL_ppaddr[OP_ENTERSUB](aTHX); |
… | |
… | |
1932 | items = AvFILLp (av) + 1; |
1940 | items = AvFILLp (av) + 1; |
1933 | } |
1941 | } |
1934 | |
1942 | |
1935 | PUTBACK; |
1943 | PUTBACK; |
1936 | |
1944 | |
1937 | slf = (struct CoroSLF *)CvXSUBANY (GvCV (gv)).any_ptr; |
1945 | ((coro_slf_cb)CvXSUBANY (GvCV (gv)).any_ptr) (aTHX_ &slf_frame, arg, items); |
1938 | slf_frame.prepare = slf->prepare; |
|
|
1939 | slf_frame.check = slf->check; |
|
|
1940 | slf->init (aTHX_ arg, items); |
|
|
1941 | } |
1946 | } |
1942 | |
1947 | |
1943 | /* now interpret the slf_frame */ |
1948 | /* now interpret the slf_frame */ |
1944 | /* we use a callback system not to make the code needlessly */ |
1949 | /* we use a callback system not to make the code needlessly */ |
1945 | /* complicated, but so we can run multiple perl coros from one cctx */ |
1950 | /* complicated, but so we can run multiple perl coros from one cctx */ |
… | |
… | |
1951 | slf_frame.prepare (aTHX_ &ta); |
1956 | slf_frame.prepare (aTHX_ &ta); |
1952 | TRANSFER (ta, 0); |
1957 | TRANSFER (ta, 0); |
1953 | |
1958 | |
1954 | checkmark = PL_stack_sp - PL_stack_base; |
1959 | checkmark = PL_stack_sp - PL_stack_base; |
1955 | } |
1960 | } |
1956 | while (slf_frame.check (aTHX)); |
1961 | while (slf_frame.check (aTHX_ &slf_frame)); |
1957 | |
1962 | |
1958 | { |
1963 | { |
1959 | dSP; |
1964 | dSP; |
1960 | SV **bot = PL_stack_base + checkmark; |
1965 | SV **bot = PL_stack_base + checkmark; |
1961 | int gimme = GIMME_V; |
1966 | int gimme = GIMME_V; |
… | |
… | |
1976 | |
1981 | |
1977 | return NORMAL; |
1982 | return NORMAL; |
1978 | } |
1983 | } |
1979 | |
1984 | |
1980 | static void |
1985 | static void |
1981 | api_execute_slf (pTHX_ CV *cv, const struct CoroSLF *slf, SV **arg, int items) |
1986 | api_execute_slf (pTHX_ CV *cv, coro_slf_cb init_cb, SV **arg, int items) |
1982 | { |
1987 | { |
1983 | assert (("FATAL: SLF call recursion in Coro module (please report)", PL_op->op_ppaddr != pp_slf)); |
|
|
1984 | assert (("FATAL: SLF call with illegal CV value", !CvANON (cv))); |
1988 | assert (("FATAL: SLF call with illegal CV value", !CvANON (cv))); |
1985 | |
1989 | |
|
|
1990 | if (PL_op->op_ppaddr != PL_ppaddr [OP_ENTERSUB] |
|
|
1991 | && PL_op->op_ppaddr != pp_slf) |
|
|
1992 | croak ("FATAL: Coro SLF calls can only be made normally, not via goto or other means, caught"); |
|
|
1993 | |
1986 | if (items > 2) |
1994 | if (items > 3) |
1987 | croak ("Coro only supports a max of two arguments to SLF functions."); |
1995 | croak ("Coro only supports up to three arguments to SLF functions currently, caught"); |
1988 | |
1996 | |
1989 | CvFLAGS (cv) |= CVf_SLF; |
1997 | CvFLAGS (cv) |= CVf_SLF; |
1990 | CvXSUBANY (cv).any_ptr = (void *)slf; |
1998 | CvXSUBANY (cv).any_ptr = (void *)init_cb; |
1991 | slf_cv = cv; |
1999 | slf_cv = cv; |
1992 | |
2000 | |
1993 | /* we patch the op, and then re-run the whole call */ |
2001 | /* we patch the op, and then re-run the whole call */ |
1994 | /* we have to put the same argument on the stack for this to work */ |
2002 | /* we have to put the same argument on the stack for this to work */ |
1995 | /* and this will be done by pp_restore */ |
2003 | /* and this will be done by pp_restore */ |
… | |
… | |
1998 | slf_restore.op_ppaddr = pp_restore; |
2006 | slf_restore.op_ppaddr = pp_restore; |
1999 | slf_restore.op_first = PL_op; |
2007 | slf_restore.op_first = PL_op; |
2000 | |
2008 | |
2001 | slf_arg0 = items > 0 ? SvREFCNT_inc (arg [0]) : 0; |
2009 | slf_arg0 = items > 0 ? SvREFCNT_inc (arg [0]) : 0; |
2002 | slf_arg1 = items > 1 ? SvREFCNT_inc (arg [1]) : 0; |
2010 | slf_arg1 = items > 1 ? SvREFCNT_inc (arg [1]) : 0; |
|
|
2011 | slf_arg2 = items > 2 ? SvREFCNT_inc (arg [2]) : 0; |
2003 | |
2012 | |
2004 | PL_op->op_ppaddr = pp_slf; |
2013 | PL_op->op_ppaddr = pp_slf; |
2005 | |
2014 | |
2006 | PL_op = (OP *)&slf_restore; |
2015 | PL_op = (OP *)&slf_restore; |
2007 | } |
2016 | } |
… | |
… | |
2044 | while (main_top_env->je_prev) |
2053 | while (main_top_env->je_prev) |
2045 | main_top_env = main_top_env->je_prev; |
2054 | main_top_env = main_top_env->je_prev; |
2046 | |
2055 | |
2047 | coroapi.ver = CORO_API_VERSION; |
2056 | coroapi.ver = CORO_API_VERSION; |
2048 | coroapi.rev = CORO_API_REVISION; |
2057 | coroapi.rev = CORO_API_REVISION; |
|
|
2058 | |
2049 | coroapi.transfer = api_transfer; |
2059 | coroapi.transfer = api_transfer; |
|
|
2060 | |
|
|
2061 | coroapi.sv_state = SvSTATE_; |
2050 | coroapi.execute_slf = api_execute_slf; |
2062 | coroapi.execute_slf = api_execute_slf; |
2051 | coroapi.sv_state = SvSTATE_; |
2063 | coroapi.prepare_nop = prepare_nop; |
|
|
2064 | coroapi.prepare_schedule = prepare_schedule; |
|
|
2065 | coroapi.prepare_cede = prepare_cede; |
|
|
2066 | coroapi.prepare_cede_notself = prepare_cede_notself; |
2052 | |
2067 | |
2053 | { |
2068 | { |
2054 | SV **svp = hv_fetch (PL_modglobal, "Time::NVtime", 12, 0); |
2069 | SV **svp = hv_fetch (PL_modglobal, "Time::NVtime", 12, 0); |
2055 | |
2070 | |
2056 | if (!svp) croak ("Time::HiRes is required"); |
2071 | if (!svp) croak ("Time::HiRes is required"); |
… | |
… | |
2092 | RETVAL |
2107 | RETVAL |
2093 | |
2108 | |
2094 | void |
2109 | void |
2095 | _set_stacklevel (...) |
2110 | _set_stacklevel (...) |
2096 | CODE: |
2111 | CODE: |
2097 | { |
|
|
2098 | static struct CoroSLF slf = { slf_init_set_stacklevel, slf_prepare_set_stacklevel, slf_check_nop }; |
|
|
2099 | api_execute_slf (aTHX_ cv, &slf, &ST (0), items); |
2112 | api_execute_slf (aTHX_ cv, slf_init_set_stacklevel, &ST (0), items); |
2100 | } |
|
|
2101 | |
2113 | |
2102 | void |
2114 | void |
2103 | transfer (...) |
2115 | transfer (...) |
2104 | CODE: |
2116 | CODE: |
2105 | { |
|
|
2106 | static struct CoroSLF slf = { slf_init_transfer, slf_prepare_transfer, slf_check_nop }; |
|
|
2107 | api_execute_slf (aTHX_ cv, &slf, &ST (0), items); |
2117 | api_execute_slf (aTHX_ cv, slf_init_transfer, &ST (0), items); |
2108 | } |
|
|
2109 | |
2118 | |
2110 | bool |
2119 | bool |
2111 | _destroy (SV *coro_sv) |
2120 | _destroy (SV *coro_sv) |
2112 | CODE: |
2121 | CODE: |
2113 | RETVAL = coro_state_destroy (aTHX_ SvSTATE (coro_sv)); |
2122 | RETVAL = coro_state_destroy (aTHX_ SvSTATE (coro_sv)); |
… | |
… | |
2276 | PROTOTYPE: $ |
2285 | PROTOTYPE: $ |
2277 | ALIAS: |
2286 | ALIAS: |
2278 | swap_defav = 1 |
2287 | swap_defav = 1 |
2279 | CODE: |
2288 | CODE: |
2280 | if (!self->slot) |
2289 | if (!self->slot) |
2281 | croak ("cannot swap state with coroutine that has no saved state"); |
2290 | croak ("cannot swap state with coroutine that has no saved state,"); |
2282 | else |
2291 | else |
2283 | { |
2292 | { |
2284 | SV **src = ix ? (SV **)&GvAV (PL_defgv) : &GvSV (PL_defgv); |
2293 | SV **src = ix ? (SV **)&GvAV (PL_defgv) : &GvSV (PL_defgv); |
2285 | SV **dst = ix ? (SV **)&self->slot->defav : (SV **)&self->slot->defsv; |
2294 | SV **dst = ix ? (SV **)&self->slot->defav : (SV **)&self->slot->defsv; |
2286 | |
2295 | |
… | |
… | |
2330 | } |
2339 | } |
2331 | |
2340 | |
2332 | void |
2341 | void |
2333 | schedule (...) |
2342 | schedule (...) |
2334 | CODE: |
2343 | CODE: |
2335 | { |
|
|
2336 | static struct CoroSLF slf = { slf_init_nop, prepare_schedule, slf_check_nop }; |
|
|
2337 | api_execute_slf (aTHX_ cv, &slf, &ST (0), items); |
2344 | api_execute_slf (aTHX_ cv, slf_init_schedule, &ST (0), items); |
2338 | } |
|
|
2339 | |
2345 | |
2340 | void |
2346 | void |
2341 | cede (...) |
2347 | cede (...) |
2342 | CODE: |
2348 | CODE: |
2343 | { |
|
|
2344 | static struct CoroSLF slf = { slf_init_nop, prepare_cede, slf_check_nop }; |
|
|
2345 | api_execute_slf (aTHX_ cv, &slf, &ST (0), items); |
2349 | api_execute_slf (aTHX_ cv, slf_init_cede, &ST (0), items); |
2346 | } |
|
|
2347 | |
2350 | |
2348 | void |
2351 | void |
2349 | cede_notself (...) |
2352 | cede_notself (...) |
2350 | CODE: |
2353 | CODE: |
2351 | { |
|
|
2352 | static struct CoroSLF slf = { slf_init_nop, prepare_cede_notself, slf_check_nop }; |
|
|
2353 | api_execute_slf (aTHX_ cv, &slf, &ST (0), items); |
2354 | api_execute_slf (aTHX_ cv, slf_init_cede_notself, &ST (0), items); |
2354 | } |
|
|
2355 | |
2355 | |
2356 | void |
2356 | void |
2357 | _set_current (SV *current) |
2357 | _set_current (SV *current) |
2358 | PROTOTYPE: $ |
2358 | PROTOTYPE: $ |
2359 | CODE: |
2359 | CODE: |