… | |
… | |
10 | #include "patchlevel.h" |
10 | #include "patchlevel.h" |
11 | |
11 | |
12 | #include <stdio.h> |
12 | #include <stdio.h> |
13 | #include <errno.h> |
13 | #include <errno.h> |
14 | #include <assert.h> |
14 | #include <assert.h> |
|
|
15 | #include <inttypes.h> /* portable stdint.h */ |
15 | |
16 | |
16 | #ifdef HAVE_MMAP |
17 | #ifdef HAVE_MMAP |
17 | # include <unistd.h> |
18 | # include <unistd.h> |
18 | # include <sys/mman.h> |
19 | # include <sys/mman.h> |
19 | # ifndef MAP_ANONYMOUS |
20 | # ifndef MAP_ANONYMOUS |
… | |
… | |
712 | PL_op = (OP *)&myop; |
713 | PL_op = (OP *)&myop; |
713 | PL_op = PL_ppaddr[OP_ENTERSUB](aTHX); |
714 | PL_op = PL_ppaddr[OP_ENTERSUB](aTHX); |
714 | SPAGAIN; |
715 | SPAGAIN; |
715 | } |
716 | } |
716 | |
717 | |
717 | ENTER; /* necessary e.g. for dounwind and to balance the xsub-entersub */ |
718 | /* this newly created coroutine might be run on an existing cctx which most |
|
|
719 | * likely was suspended in set_stacklevel, called from entersub. |
|
|
720 | * set_stacklevl doesn't do anything on return, but entersub does LEAVE, |
|
|
721 | * so we ENTER here for symmetry |
|
|
722 | */ |
|
|
723 | ENTER; |
718 | } |
724 | } |
719 | |
725 | |
720 | static void |
726 | static void |
721 | coro_destroy (pTHX_ struct coro *coro) |
727 | coro_destroy (pTHX_ struct coro *coro) |
722 | { |
728 | { |
… | |
… | |
1523 | |
1529 | |
1524 | while (main_top_env->je_prev) |
1530 | while (main_top_env->je_prev) |
1525 | main_top_env = main_top_env->je_prev; |
1531 | main_top_env = main_top_env->je_prev; |
1526 | |
1532 | |
1527 | coroapi.ver = CORO_API_VERSION; |
1533 | coroapi.ver = CORO_API_VERSION; |
|
|
1534 | coroapi.rev = CORO_API_REVISION; |
1528 | coroapi.transfer = api_transfer; |
1535 | coroapi.transfer = api_transfer; |
1529 | |
1536 | |
1530 | assert (("PRIO_NORMAL must be 0", !PRIO_NORMAL)); |
1537 | assert (("PRIO_NORMAL must be 0", !PRIO_NORMAL)); |
1531 | } |
1538 | } |
1532 | |
1539 | |
… | |
… | |
1599 | |
1606 | |
1600 | break; |
1607 | break; |
1601 | } |
1608 | } |
1602 | |
1609 | |
1603 | BARRIER; |
1610 | BARRIER; |
|
|
1611 | PUTBACK; |
1604 | TRANSFER (ta); |
1612 | TRANSFER (ta); |
1605 | |
1613 | SPAGAIN; /* might be the sp of a different coroutine now */ |
1606 | if (expect_false (GIMME_V != G_VOID && ta.next != ta.prev)) |
1614 | /* be extra careful not to ever do anything after TRANSFER */ |
1607 | XSRETURN_YES; |
|
|
1608 | } |
1615 | } |
1609 | |
1616 | |
1610 | bool |
1617 | bool |
1611 | _destroy (SV *coro_sv) |
1618 | _destroy (SV *coro_sv) |
1612 | CODE: |
1619 | CODE: |
… | |
… | |
1672 | |
1679 | |
1673 | { |
1680 | { |
1674 | dSP; |
1681 | dSP; |
1675 | ENTER; |
1682 | ENTER; |
1676 | SAVETMPS; |
1683 | SAVETMPS; |
|
|
1684 | PUTBACK; |
|
|
1685 | PUSHSTACK; |
1677 | PUSHMARK (SP); |
1686 | PUSHMARK (SP); |
1678 | PUTBACK; |
|
|
1679 | |
1687 | |
1680 | if (ix) |
1688 | if (ix) |
1681 | eval_sv (coderef, 0); |
1689 | eval_sv (coderef, 0); |
1682 | else |
1690 | else |
1683 | call_sv (coderef, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD); |
1691 | call_sv (coderef, G_KEEPERR | G_EVAL | G_VOID | G_DISCARD); |
1684 | |
1692 | |
|
|
1693 | POPSTACK; |
1685 | SPAGAIN; |
1694 | SPAGAIN; |
1686 | FREETMPS; |
1695 | FREETMPS; |
1687 | LEAVE; |
1696 | LEAVE; |
1688 | PUTBACK; |
1697 | PUTBACK; |
1689 | } |
1698 | } |