aboutsummaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldo.c')
-rw-r--r--ldo.c40
1 files changed, 16 insertions, 24 deletions
diff --git a/ldo.c b/ldo.c
index 056fef0c..f8d8f11c 100644
--- a/ldo.c
+++ b/ldo.c
@@ -138,7 +138,7 @@ l_noret luaD_throw (lua_State *L, int errcode) {
138 138
139 139
140int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { 140int 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*/
518void luaD_callnoyield (lua_State *L, StkId func, int nResults) { 521void 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) {
664LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs, 661LUA_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
707LUA_API int lua_isyieldable (lua_State *L) { 701LUA_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*/
747int luaD_pcall (lua_State *L, Pfunc func, void *u, 741int 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