… | |
… | |
716 | return rss; |
716 | return rss; |
717 | } |
717 | } |
718 | |
718 | |
719 | /** set stacklevel support **************************************************/ |
719 | /** set stacklevel support **************************************************/ |
720 | |
720 | |
721 | /* we sometimes need to create the effect of pp_set_stacklevel calling us */ |
721 | /* we sometimes need to create the effect of pp_slf calling us */ |
722 | #define SSL_HEAD (void)0 |
722 | #define SLF_HEAD (void)0 |
723 | /* we sometimes need to create the effect of leaving via pp_set_stacklevel */ |
723 | /* we sometimes need to create the effect of leaving via pp_slf */ |
724 | #define SSL_TAIL set_stacklevel_tail (aTHX) |
724 | #define SLF_TAIL slf_tail (aTHX) |
725 | |
725 | |
726 | INLINE void |
726 | INLINE void |
727 | set_stacklevel_tail (pTHX) |
727 | slf_tail (pTHX) |
728 | { |
728 | { |
729 | dSP; |
729 | dSP; |
730 | SV **bot = SP; |
730 | SV **bot = SP; |
731 | |
731 | |
732 | int gimme = GIMME_V; |
732 | int gimme = GIMME_V; |
… | |
… | |
885 | |
885 | |
886 | /* this newly created coroutine might be run on an existing cctx which most |
886 | /* this newly created coroutine might be run on an existing cctx which most |
887 | * likely was suspended in set_stacklevel, called from pp_set_stacklevel, |
887 | * likely was suspended in set_stacklevel, called from pp_set_stacklevel, |
888 | * so we have to emulate entering pp_set_stacklevel here. |
888 | * so we have to emulate entering pp_set_stacklevel here. |
889 | */ |
889 | */ |
890 | SSL_HEAD; |
890 | SLF_HEAD; |
891 | } |
891 | } |
892 | |
892 | |
893 | static void |
893 | static void |
894 | coro_destruct (pTHX_ struct coro *coro) |
894 | coro_destruct (pTHX_ struct coro *coro) |
895 | { |
895 | { |
… | |
… | |
1131 | { |
1131 | { |
1132 | dTHX; |
1132 | dTHX; |
1133 | |
1133 | |
1134 | /* we are the alternative tail to pp_set_stacklevel */ |
1134 | /* we are the alternative tail to pp_set_stacklevel */ |
1135 | /* so do the same things here */ |
1135 | /* so do the same things here */ |
1136 | SSL_TAIL; |
1136 | SLF_TAIL; |
1137 | |
1137 | |
1138 | /* we now skip the op that did lead to transfer() */ |
1138 | /* we now skip the op that did lead to transfer() */ |
1139 | PL_op = PL_op->op_next; |
1139 | PL_op = PL_op->op_next; |
1140 | |
1140 | |
1141 | /* inject a fake subroutine call to cctx_init */ |
1141 | /* inject a fake subroutine call to cctx_init */ |
… | |
… | |
1836 | PerlIOBuf_set_ptrcnt, |
1836 | PerlIOBuf_set_ptrcnt, |
1837 | }; |
1837 | }; |
1838 | |
1838 | |
1839 | /*****************************************************************************/ |
1839 | /*****************************************************************************/ |
1840 | |
1840 | |
1841 | static const CV *ssl_cv; /* for quick consistency check */ |
1841 | static const CV *slf_cv; /* for quick consistency check */ |
1842 | |
1842 | |
1843 | static UNOP ssl_restore; /* restore stack as entersub did, for first-re-run */ |
1843 | static UNOP slf_restore; /* restore stack as entersub did, for first-re-run */ |
1844 | static SV *ssl_arg0; |
1844 | static SV *slf_arg0; |
1845 | static SV *ssl_arg1; |
1845 | static SV *slf_arg1; |
1846 | |
1846 | |
1847 | /* this restores the stack in the case we patched the entersub, to */ |
1847 | /* this restores the stack in the case we patched the entersub, to */ |
1848 | /* recreate the stack frame as perl will on following calls */ |
1848 | /* recreate the stack frame as perl will on following calls */ |
1849 | /* since entersub cleared the stack */ |
1849 | /* since entersub cleared the stack */ |
1850 | static OP * |
1850 | static OP * |
… | |
… | |
1853 | dSP; |
1853 | dSP; |
1854 | |
1854 | |
1855 | PUSHMARK (SP); |
1855 | PUSHMARK (SP); |
1856 | |
1856 | |
1857 | EXTEND (SP, 3); |
1857 | EXTEND (SP, 3); |
1858 | if (ssl_arg0) PUSHs (sv_2mortal (ssl_arg0)), ssl_arg0 = 0; |
1858 | if (slf_arg0) PUSHs (sv_2mortal (slf_arg0)); |
1859 | if (ssl_arg1) PUSHs (sv_2mortal (ssl_arg1)), ssl_arg1 = 0; |
1859 | if (slf_arg1) PUSHs (sv_2mortal (slf_arg1)); |
1860 | PUSHs ((SV *)CvGV (ssl_cv)); |
1860 | PUSHs ((SV *)CvGV (slf_cv)); |
1861 | |
1861 | |
1862 | RETURNOP (ssl_restore.op_first); |
1862 | RETURNOP (slf_restore.op_first); |
1863 | } |
1863 | } |
1864 | |
1864 | |
1865 | #define OPpENTERSUB_SSL 15 /* the part of op_private entersub hopefully doesn't use */ |
1865 | #define OPpENTERSUB_SLF 15 /* the part of op_private entersub hopefully doesn't use */ |
1866 | |
1866 | |
1867 | /* declare prototype */ |
1867 | /* declare prototype */ |
1868 | XS(XS_Coro__State__set_stacklevel); |
1868 | XS(XS_Coro__State__set_stacklevel); |
1869 | |
1869 | |
1870 | /* |
1870 | /* |
1871 | * these not obviously related functions are all rolled into one |
1871 | * these not obviously related functions are all rolled into one |
1872 | * function to increase chances that they all will call transfer with the same |
1872 | * function to increase chances that they all will call transfer with the same |
1873 | * stack offset |
1873 | * stack offset |
|
|
1874 | * SLF stands for "schedule-like-function". |
1874 | */ |
1875 | */ |
1875 | static OP * |
1876 | static OP * |
1876 | pp_set_stacklevel (pTHX) |
1877 | pp_slf (pTHX) |
1877 | { |
1878 | { |
1878 | dSP; |
1879 | dSP; |
1879 | struct transfer_args ta; |
1880 | struct transfer_args ta; |
1880 | SV **arg = PL_stack_base + TOPMARK + 1; |
1881 | SV **arg = PL_stack_base + TOPMARK + 1; |
1881 | int items = SP - arg; /* args without function object */ |
1882 | int items = SP - arg; /* args without function object */ |
… | |
… | |
1895 | arg = AvARRAY (av); |
1896 | arg = AvARRAY (av); |
1896 | items = AvFILLp (av) + 1; |
1897 | items = AvFILLp (av) + 1; |
1897 | } |
1898 | } |
1898 | |
1899 | |
1899 | PUTBACK; |
1900 | PUTBACK; |
1900 | switch (PL_op->op_private & OPpENTERSUB_SSL) |
1901 | switch (PL_op->op_private & OPpENTERSUB_SLF) |
1901 | { |
1902 | { |
1902 | case 0: |
1903 | case 0: |
1903 | prepare_set_stacklevel (&ta, (struct coro_cctx *)SvIV (arg [0])); |
1904 | prepare_set_stacklevel (&ta, (struct coro_cctx *)SvIV (arg [0])); |
1904 | break; |
1905 | break; |
1905 | |
1906 | |
… | |
… | |
1919 | break; |
1920 | break; |
1920 | |
1921 | |
1921 | case 4: |
1922 | case 4: |
1922 | prepare_cede_notself (aTHX_ &ta); |
1923 | prepare_cede_notself (aTHX_ &ta); |
1923 | break; |
1924 | break; |
|
|
1925 | |
|
|
1926 | case 5: |
|
|
1927 | abort (); |
|
|
1928 | |
|
|
1929 | default: |
|
|
1930 | abort (); |
1924 | } |
1931 | } |
1925 | |
1932 | |
1926 | TRANSFER (ta, 0); |
1933 | TRANSFER (ta, 0); |
1927 | SPAGAIN; |
1934 | SPAGAIN; |
1928 | |
1935 | |
1929 | skip: |
|
|
1930 | PUTBACK; |
1936 | PUTBACK; |
1931 | SSL_TAIL; |
1937 | SLF_TAIL; |
1932 | SPAGAIN; |
1938 | SPAGAIN; |
1933 | RETURN; |
1939 | RETURN; |
1934 | } |
1940 | } |
1935 | |
1941 | |
1936 | static void |
1942 | static void |
1937 | coro_ssl_patch (pTHX_ CV *cv, int ix, SV **args, int items) |
1943 | coro_slf_patch (pTHX_ CV *cv, int ix, SV **args, int items) |
1938 | { |
1944 | { |
1939 | assert (("FATAL: ssl call recursion in Coro module (please report)", PL_op->op_ppaddr != pp_set_stacklevel)); |
1945 | assert (("FATAL: SLF call recursion in Coro module (please report)", PL_op->op_ppaddr != pp_slf)); |
1940 | |
1946 | |
1941 | assert (("FATAL: ssl call with illegal CV value", CvGV (cv))); |
1947 | assert (("FATAL: SLF call with illegal CV value", CvGV (cv))); |
1942 | ssl_cv = cv; |
1948 | slf_cv = cv; |
1943 | |
1949 | |
1944 | /* we patch the op, and then re-run the whole call */ |
1950 | /* we patch the op, and then re-run the whole call */ |
1945 | /* we have to put some dummy argument on the stack for this to work */ |
1951 | /* we have to put the same argument on the stack for this to work */ |
|
|
1952 | /* and this will be done by pp_restore */ |
1946 | ssl_restore.op_next = (OP *)&ssl_restore; |
1953 | slf_restore.op_next = (OP *)&slf_restore; |
1947 | ssl_restore.op_type = OP_NULL; |
1954 | slf_restore.op_type = OP_NULL; |
1948 | ssl_restore.op_ppaddr = pp_restore; |
1955 | slf_restore.op_ppaddr = pp_restore; |
1949 | ssl_restore.op_first = PL_op; |
1956 | slf_restore.op_first = PL_op; |
1950 | |
1957 | |
1951 | ssl_arg0 = items > 0 ? SvREFCNT_inc (args [0]) : 0; |
1958 | slf_arg0 = items > 0 ? SvREFCNT_inc (args [0]) : 0; |
1952 | ssl_arg1 = items > 1 ? SvREFCNT_inc (args [1]) : 0; |
1959 | slf_arg1 = items > 1 ? SvREFCNT_inc (args [1]) : 0; |
1953 | |
1960 | |
1954 | PL_op->op_ppaddr = pp_set_stacklevel; |
1961 | PL_op->op_ppaddr = pp_slf; |
1955 | PL_op->op_private = PL_op->op_private & ~OPpENTERSUB_SSL | ix; /* we potentially share our private flags with entersub */ |
1962 | PL_op->op_private = PL_op->op_private & ~OPpENTERSUB_SLF | ix; /* we potentially share our private flags with entersub */ |
1956 | |
1963 | |
1957 | PL_op = (OP *)&ssl_restore; |
1964 | PL_op = (OP *)&slf_restore; |
1958 | } |
1965 | } |
1959 | |
1966 | |
1960 | MODULE = Coro::State PACKAGE = Coro::State PREFIX = api_ |
1967 | MODULE = Coro::State PACKAGE = Coro::State PREFIX = api_ |
1961 | |
1968 | |
1962 | PROTOTYPES: DISABLE |
1969 | PROTOTYPES: DISABLE |
… | |
… | |
2046 | Coro::State::transfer = 1 |
2053 | Coro::State::transfer = 1 |
2047 | Coro::schedule = 2 |
2054 | Coro::schedule = 2 |
2048 | Coro::cede = 3 |
2055 | Coro::cede = 3 |
2049 | Coro::cede_notself = 4 |
2056 | Coro::cede_notself = 4 |
2050 | CODE: |
2057 | CODE: |
2051 | coro_ssl_patch (aTHX_ cv, ix, &ST (0), items); |
2058 | coro_slf_patch (aTHX_ cv, ix, &ST (0), items); |
2052 | |
2059 | |
2053 | bool |
2060 | bool |
2054 | _destroy (SV *coro_sv) |
2061 | _destroy (SV *coro_sv) |
2055 | CODE: |
2062 | CODE: |
2056 | RETVAL = coro_state_destroy (aTHX_ SvSTATE (coro_sv)); |
2063 | RETVAL = coro_state_destroy (aTHX_ SvSTATE (coro_sv)); |