diff options
Diffstat (limited to 'ldo.c')
-rw-r--r-- | ldo.c | 40 |
1 files changed, 16 insertions, 24 deletions
@@ -138,7 +138,7 @@ l_noret luaD_throw (lua_State *L, int errcode) { | |||
138 | 138 | ||
139 | 139 | ||
140 | int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { | 140 | int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { |
141 | unsigned short oldnCcalls = L->nCcalls - L->nci; | 141 | l_uint32 oldnCcalls = L->nCcalls - L->nci; |
142 | struct lua_longjmp lj; | 142 | struct lua_longjmp lj; |
143 | lua_assert(L->nCcalls >= L->nci); | 143 | lua_assert(L->nCcalls >= L->nci); |
144 | lj.status = LUA_OK; | 144 | lj.status = LUA_OK; |
@@ -513,12 +513,17 @@ void luaD_call (lua_State *L, StkId func, int nresults) { | |||
513 | 513 | ||
514 | 514 | ||
515 | /* | 515 | /* |
516 | ** Similar to 'luaD_call', but does not allow yields during the call | 516 | ** Similar to 'luaD_call', but does not allow yields during the call. |
517 | ** If there is a stack overflow, freeing all CI structures will | ||
518 | ** force the subsequent call to invoke 'luaE_extendCI', which then | ||
519 | ** will raise any errors. | ||
517 | */ | 520 | */ |
518 | void luaD_callnoyield (lua_State *L, StkId func, int nResults) { | 521 | void luaD_callnoyield (lua_State *L, StkId func, int nResults) { |
519 | L->nny++; | 522 | incXCcalls(L); |
523 | if (getCcalls(L) >= LUAI_MAXCCALLS) /* possible stack overflow? */ | ||
524 | luaE_freeCI(L); | ||
520 | luaD_call(L, func, nResults); | 525 | luaD_call(L, func, nResults); |
521 | L->nny--; | 526 | decXCcalls(L); |
522 | } | 527 | } |
523 | 528 | ||
524 | 529 | ||
@@ -530,7 +535,7 @@ static void finishCcall (lua_State *L, int status) { | |||
530 | CallInfo *ci = L->ci; | 535 | CallInfo *ci = L->ci; |
531 | int n; | 536 | int n; |
532 | /* must have a continuation and must be able to call it */ | 537 | /* must have a continuation and must be able to call it */ |
533 | lua_assert(ci->u.c.k != NULL && L->nny == 0); | 538 | lua_assert(ci->u.c.k != NULL && yieldable(L)); |
534 | /* error status can only happen in a protected call */ | 539 | /* error status can only happen in a protected call */ |
535 | lua_assert((ci->callstatus & CIST_YPCALL) || status == LUA_YIELD); | 540 | lua_assert((ci->callstatus & CIST_YPCALL) || status == LUA_YIELD); |
536 | if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */ | 541 | if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */ |
@@ -601,7 +606,6 @@ static int recover (lua_State *L, int status) { | |||
601 | luaD_seterrorobj(L, status, oldtop); | 606 | luaD_seterrorobj(L, status, oldtop); |
602 | L->ci = ci; | 607 | L->ci = ci; |
603 | L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */ | 608 | L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */ |
604 | L->nny = 0; /* should be zero to be yieldable */ | ||
605 | luaD_shrinkstack(L); | 609 | luaD_shrinkstack(L); |
606 | L->errfunc = ci->u.c.old_errfunc; | 610 | L->errfunc = ci->u.c.old_errfunc; |
607 | return 1; /* continue running the coroutine */ | 611 | return 1; /* continue running the coroutine */ |
@@ -623,13 +627,6 @@ static int resume_error (lua_State *L, const char *msg, int narg) { | |||
623 | 627 | ||
624 | 628 | ||
625 | /* | 629 | /* |
626 | ** "Cost" in the C stack for a coroutine invocation. | ||
627 | */ | ||
628 | #if !defined(LUAL_COROCSTK) | ||
629 | #define LUAL_COROCSTK 3 | ||
630 | #endif | ||
631 | |||
632 | /* | ||
633 | ** Do the work for 'lua_resume' in protected mode. Most of the work | 630 | ** Do the work for 'lua_resume' in protected mode. Most of the work |
634 | ** depends on the status of the coroutine: initial state, suspended | 631 | ** depends on the status of the coroutine: initial state, suspended |
635 | ** inside a hook, or regularly suspended (optionally with a continuation | 632 | ** inside a hook, or regularly suspended (optionally with a continuation |
@@ -664,7 +661,6 @@ static void resume (lua_State *L, void *ud) { | |||
664 | LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs, | 661 | LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs, |
665 | int *nresults) { | 662 | int *nresults) { |
666 | int status; | 663 | int status; |
667 | unsigned short oldnny = L->nny; /* save "number of non-yieldable" calls */ | ||
668 | lua_lock(L); | 664 | lua_lock(L); |
669 | if (L->status == LUA_OK) { /* may be starting a coroutine */ | 665 | if (L->status == LUA_OK) { /* may be starting a coroutine */ |
670 | if (L->ci != &L->base_ci) /* not in base level? */ | 666 | if (L->ci != &L->base_ci) /* not in base level? */ |
@@ -675,11 +671,10 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs, | |||
675 | if (from == NULL) | 671 | if (from == NULL) |
676 | L->nCcalls = 1; | 672 | L->nCcalls = 1; |
677 | else /* correct 'nCcalls' for this thread */ | 673 | else /* correct 'nCcalls' for this thread */ |
678 | L->nCcalls = from->nCcalls - from->nci + L->nci + LUAL_COROCSTK; | 674 | L->nCcalls = getCcalls(from) - from->nci + L->nci + CSTACKCF; |
679 | if (L->nCcalls >= LUAI_MAXCCALLS) | 675 | if (L->nCcalls >= LUAI_MAXCCALLS) |
680 | return resume_error(L, "C stack overflow", nargs); | 676 | return resume_error(L, "C stack overflow", nargs); |
681 | luai_userstateresume(L, nargs); | 677 | luai_userstateresume(L, nargs); |
682 | L->nny = 0; /* allow yields */ | ||
683 | api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); | 678 | api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); |
684 | status = luaD_rawrunprotected(L, resume, &nargs); | 679 | status = luaD_rawrunprotected(L, resume, &nargs); |
685 | /* continue running after recoverable errors */ | 680 | /* continue running after recoverable errors */ |
@@ -698,14 +693,13 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs, | |||
698 | } | 693 | } |
699 | *nresults = (status == LUA_YIELD) ? L->ci->u2.nyield | 694 | *nresults = (status == LUA_YIELD) ? L->ci->u2.nyield |
700 | : cast_int(L->top - (L->ci->func + 1)); | 695 | : cast_int(L->top - (L->ci->func + 1)); |
701 | L->nny = oldnny; /* restore 'nny' */ | ||
702 | lua_unlock(L); | 696 | lua_unlock(L); |
703 | return status; | 697 | return status; |
704 | } | 698 | } |
705 | 699 | ||
706 | 700 | ||
707 | LUA_API int lua_isyieldable (lua_State *L) { | 701 | LUA_API int lua_isyieldable (lua_State *L) { |
708 | return (L->nny == 0); | 702 | return yieldable(L); |
709 | } | 703 | } |
710 | 704 | ||
711 | 705 | ||
@@ -715,7 +709,7 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx, | |||
715 | luai_userstateyield(L, nresults); | 709 | luai_userstateyield(L, nresults); |
716 | lua_lock(L); | 710 | lua_lock(L); |
717 | api_checknelems(L, nresults); | 711 | api_checknelems(L, nresults); |
718 | if (unlikely(L->nny > 0)) { | 712 | if (unlikely(!yieldable(L))) { |
719 | if (L != G(L)->mainthread) | 713 | if (L != G(L)->mainthread) |
720 | luaG_runerror(L, "attempt to yield across a C-call boundary"); | 714 | luaG_runerror(L, "attempt to yield across a C-call boundary"); |
721 | else | 715 | else |
@@ -741,7 +735,7 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx, | |||
741 | 735 | ||
742 | /* | 736 | /* |
743 | ** Call the C function 'func' in protected mode, restoring basic | 737 | ** Call the C function 'func' in protected mode, restoring basic |
744 | ** thread information ('allowhook', 'nny', etc.) and in particular | 738 | ** thread information ('allowhook', etc.) and in particular |
745 | ** its stack level in case of errors. | 739 | ** its stack level in case of errors. |
746 | */ | 740 | */ |
747 | int luaD_pcall (lua_State *L, Pfunc func, void *u, | 741 | int luaD_pcall (lua_State *L, Pfunc func, void *u, |
@@ -749,7 +743,6 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u, | |||
749 | int status; | 743 | int status; |
750 | CallInfo *old_ci = L->ci; | 744 | CallInfo *old_ci = L->ci; |
751 | lu_byte old_allowhooks = L->allowhook; | 745 | lu_byte old_allowhooks = L->allowhook; |
752 | unsigned short old_nny = L->nny; | ||
753 | ptrdiff_t old_errfunc = L->errfunc; | 746 | ptrdiff_t old_errfunc = L->errfunc; |
754 | L->errfunc = ef; | 747 | L->errfunc = ef; |
755 | status = luaD_rawrunprotected(L, func, u); | 748 | status = luaD_rawrunprotected(L, func, u); |
@@ -757,7 +750,6 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u, | |||
757 | StkId oldtop = restorestack(L, old_top); | 750 | StkId oldtop = restorestack(L, old_top); |
758 | L->ci = old_ci; | 751 | L->ci = old_ci; |
759 | L->allowhook = old_allowhooks; | 752 | L->allowhook = old_allowhooks; |
760 | L->nny = old_nny; | ||
761 | status = luaF_close(L, oldtop, status); | 753 | status = luaF_close(L, oldtop, status); |
762 | oldtop = restorestack(L, old_top); /* previous call may change stack */ | 754 | oldtop = restorestack(L, old_top); /* previous call may change stack */ |
763 | luaD_seterrorobj(L, status, oldtop); | 755 | luaD_seterrorobj(L, status, oldtop); |
@@ -811,7 +803,7 @@ int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, | |||
811 | const char *mode) { | 803 | const char *mode) { |
812 | struct SParser p; | 804 | struct SParser p; |
813 | int status; | 805 | int status; |
814 | L->nny++; /* cannot yield during parsing */ | 806 | incnny(L); /* cannot yield during parsing */ |
815 | p.z = z; p.name = name; p.mode = mode; | 807 | p.z = z; p.name = name; p.mode = mode; |
816 | p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0; | 808 | p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0; |
817 | p.dyd.gt.arr = NULL; p.dyd.gt.size = 0; | 809 | p.dyd.gt.arr = NULL; p.dyd.gt.size = 0; |
@@ -822,7 +814,7 @@ int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, | |||
822 | luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size); | 814 | luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size); |
823 | luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size); | 815 | luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size); |
824 | luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size); | 816 | luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size); |
825 | L->nny--; | 817 | decnny(L); |
826 | return status; | 818 | return status; |
827 | } | 819 | } |
828 | 820 | ||