aboutsummaryrefslogtreecommitdiff
path: root/src/lua/ldo.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lua/ldo.c')
-rw-r--r--src/lua/ldo.c125
1 files changed, 91 insertions, 34 deletions
diff --git a/src/lua/ldo.c b/src/lua/ldo.c
index 4b55c31..aa159cf 100644
--- a/src/lua/ldo.c
+++ b/src/lua/ldo.c
@@ -98,11 +98,12 @@ void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) {
98 setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); 98 setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling"));
99 break; 99 break;
100 } 100 }
101 case CLOSEPROTECT: { 101 case LUA_OK: { /* special case only for closing upvalues */
102 setnilvalue(s2v(oldtop)); /* no error message */ 102 setnilvalue(s2v(oldtop)); /* no error message */
103 break; 103 break;
104 } 104 }
105 default: { 105 default: {
106 lua_assert(errorstatus(errcode)); /* real error */
106 setobjs2s(L, oldtop, L->top - 1); /* error message on current top */ 107 setobjs2s(L, oldtop, L->top - 1); /* error message on current top */
107 break; 108 break;
108 } 109 }
@@ -118,17 +119,13 @@ l_noret luaD_throw (lua_State *L, int errcode) {
118 } 119 }
119 else { /* thread has no error handler */ 120 else { /* thread has no error handler */
120 global_State *g = G(L); 121 global_State *g = G(L);
121 errcode = luaF_close(L, L->stack, errcode); /* close all upvalues */ 122 errcode = luaE_resetthread(L, errcode); /* close all upvalues */
122 L->status = cast_byte(errcode); /* mark it as dead */
123 if (g->mainthread->errorJmp) { /* main thread has a handler? */ 123 if (g->mainthread->errorJmp) { /* main thread has a handler? */
124 setobjs2s(L, g->mainthread->top++, L->top - 1); /* copy error obj. */ 124 setobjs2s(L, g->mainthread->top++, L->top - 1); /* copy error obj. */
125 luaD_throw(g->mainthread, errcode); /* re-throw in main thread */ 125 luaD_throw(g->mainthread, errcode); /* re-throw in main thread */
126 } 126 }
127 else { /* no handler at all; abort */ 127 else { /* no handler at all; abort */
128 if (g->panic) { /* panic function? */ 128 if (g->panic) { /* panic function? */
129 luaD_seterrorobj(L, errcode, L->top); /* assume EXTRA_STACK */
130 if (L->ci->top < L->top)
131 L->ci->top = L->top; /* pushing msg. can break this invariant */
132 lua_unlock(L); 129 lua_unlock(L);
133 g->panic(L); /* call panic function (last chance to jump out) */ 130 g->panic(L); /* call panic function (last chance to jump out) */
134 } 131 }
@@ -375,7 +372,7 @@ void luaD_tryfuncTM (lua_State *L, StkId func) {
375 const TValue *tm = luaT_gettmbyobj(L, s2v(func), TM_CALL); 372 const TValue *tm = luaT_gettmbyobj(L, s2v(func), TM_CALL);
376 StkId p; 373 StkId p;
377 if (unlikely(ttisnil(tm))) 374 if (unlikely(ttisnil(tm)))
378 luaG_typeerror(L, s2v(func), "call"); /* nothing to call */ 375 luaG_callerror(L, s2v(func)); /* nothing to call */
379 for (p = L->top; p > func; p--) /* open space for metamethod */ 376 for (p = L->top; p > func; p--) /* open space for metamethod */
380 setobjs2s(L, p, p-1); 377 setobjs2s(L, p, p-1);
381 L->top++; /* stack space pre-allocated by the caller */ 378 L->top++; /* stack space pre-allocated by the caller */
@@ -409,7 +406,7 @@ static void moveresults (lua_State *L, StkId res, int nres, int wanted) {
409 default: /* multiple results (or to-be-closed variables) */ 406 default: /* multiple results (or to-be-closed variables) */
410 if (hastocloseCfunc(wanted)) { /* to-be-closed variables? */ 407 if (hastocloseCfunc(wanted)) { /* to-be-closed variables? */
411 ptrdiff_t savedres = savestack(L, res); 408 ptrdiff_t savedres = savestack(L, res);
412 luaF_close(L, res, LUA_OK); /* may change the stack */ 409 luaF_close(L, res, CLOSEKTOP, 0); /* may change the stack */
413 res = restorestack(L, savedres); 410 res = restorestack(L, savedres);
414 wanted = codeNresults(wanted); /* correct value */ 411 wanted = codeNresults(wanted); /* correct value */
415 if (wanted == LUA_MULTRET) 412 if (wanted == LUA_MULTRET)
@@ -596,15 +593,11 @@ static void finishCcall (lua_State *L, int status) {
596/* 593/*
597** Executes "full continuation" (everything in the stack) of a 594** Executes "full continuation" (everything in the stack) of a
598** previously interrupted coroutine until the stack is empty (or another 595** previously interrupted coroutine until the stack is empty (or another
599** interruption long-jumps out of the loop). If the coroutine is 596** interruption long-jumps out of the loop).
600** recovering from an error, 'ud' points to the error status, which must
601** be passed to the first continuation function (otherwise the default
602** status is LUA_YIELD).
603*/ 597*/
604static void unroll (lua_State *L, void *ud) { 598static void unroll (lua_State *L, void *ud) {
605 CallInfo *ci; 599 CallInfo *ci;
606 if (ud != NULL) /* error status? */ 600 UNUSED(ud);
607 finishCcall(L, *(int *)ud); /* finish 'lua_pcallk' callee */
608 while ((ci = L->ci) != &L->base_ci) { /* something in the stack */ 601 while ((ci = L->ci) != &L->base_ci) { /* something in the stack */
609 if (!isLua(ci)) /* C function? */ 602 if (!isLua(ci)) /* C function? */
610 finishCcall(L, LUA_YIELD); /* complete its execution */ 603 finishCcall(L, LUA_YIELD); /* complete its execution */
@@ -631,24 +624,36 @@ static CallInfo *findpcall (lua_State *L) {
631 624
632 625
633/* 626/*
634** Recovers from an error in a coroutine. Finds a recover point (if 627** Auxiliary structure to call 'recover' in protected mode.
635** there is one) and completes the execution of the interrupted
636** 'luaD_pcall'. If there is no recover point, returns zero.
637*/ 628*/
638static int recover (lua_State *L, int status) { 629struct RecoverS {
639 StkId oldtop; 630 int status;
640 CallInfo *ci = findpcall(L); 631 CallInfo *ci;
641 if (ci == NULL) return 0; /* no recovery point */ 632};
633
634
635/*
636** Recovers from an error in a coroutine: completes the execution of the
637** interrupted 'luaD_pcall', completes the interrupted C function which
638** called 'lua_pcallk', and continues running the coroutine. If there is
639** an error in 'luaF_close', this function will be called again and the
640** coroutine will continue from where it left.
641*/
642static void recover (lua_State *L, void *ud) {
643 struct RecoverS *r = cast(struct RecoverS *, ud);
644 int status = r->status;
645 CallInfo *ci = r->ci; /* recover point */
646 StkId func = restorestack(L, ci->u2.funcidx);
642 /* "finish" luaD_pcall */ 647 /* "finish" luaD_pcall */
643 oldtop = restorestack(L, ci->u2.funcidx);
644 L->ci = ci; 648 L->ci = ci;
645 L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */ 649 L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */
646 status = luaF_close(L, oldtop, status); /* may change the stack */ 650 luaF_close(L, func, status, 0); /* may change the stack */
647 oldtop = restorestack(L, ci->u2.funcidx); 651 func = restorestack(L, ci->u2.funcidx);
648 luaD_seterrorobj(L, status, oldtop); 652 luaD_seterrorobj(L, status, func);
649 luaD_shrinkstack(L); /* restore stack size in case of overflow */ 653 luaD_shrinkstack(L); /* restore stack size in case of overflow */
650 L->errfunc = ci->u.c.old_errfunc; 654 L->errfunc = ci->u.c.old_errfunc;
651 return 1; /* continue running the coroutine */ 655 finishCcall(L, status); /* finish 'lua_pcallk' callee */
656 unroll(L, NULL); /* continue running the coroutine */
652} 657}
653 658
654 659
@@ -698,6 +703,24 @@ static void resume (lua_State *L, void *ud) {
698 } 703 }
699} 704}
700 705
706
707/*
708** Calls 'recover' in protected mode, repeating while there are
709** recoverable errors, that is, errors inside a protected call. (Any
710** error interrupts 'recover', and this loop protects it again so it
711** can continue.) Stops with a normal end (status == LUA_OK), an yield
712** (status == LUA_YIELD), or an unprotected error ('findpcall' doesn't
713** find a recover point).
714*/
715static int p_recover (lua_State *L, int status) {
716 struct RecoverS r;
717 r.status = status;
718 while (errorstatus(status) && (r.ci = findpcall(L)) != NULL)
719 r.status = luaD_rawrunprotected(L, recover, &r);
720 return r.status;
721}
722
723
701LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs, 724LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs,
702 int *nresults) { 725 int *nresults) {
703 int status; 726 int status;
@@ -715,10 +738,7 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs,
715 api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); 738 api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
716 status = luaD_rawrunprotected(L, resume, &nargs); 739 status = luaD_rawrunprotected(L, resume, &nargs);
717 /* continue running after recoverable errors */ 740 /* continue running after recoverable errors */
718 while (errorstatus(status) && recover(L, status)) { 741 status = p_recover(L, status);
719 /* unroll continuation */
720 status = luaD_rawrunprotected(L, unroll, &status);
721 }
722 if (likely(!errorstatus(status))) 742 if (likely(!errorstatus(status)))
723 lua_assert(status == L->status); /* normal end or yield */ 743 lua_assert(status == L->status); /* normal end or yield */
724 else { /* unrecoverable error */ 744 else { /* unrecoverable error */
@@ -770,6 +790,45 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
770 790
771 791
772/* 792/*
793** Auxiliary structure to call 'luaF_close' in protected mode.
794*/
795struct CloseP {
796 StkId level;
797 int status;
798};
799
800
801/*
802** Auxiliary function to call 'luaF_close' in protected mode.
803*/
804static void closepaux (lua_State *L, void *ud) {
805 struct CloseP *pcl = cast(struct CloseP *, ud);
806 luaF_close(L, pcl->level, pcl->status, 0);
807}
808
809
810/*
811** Calls 'luaF_close' in protected mode. Return the original status
812** or, in case of errors, the new status.
813*/
814int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status) {
815 CallInfo *old_ci = L->ci;
816 lu_byte old_allowhooks = L->allowhook;
817 for (;;) { /* keep closing upvalues until no more errors */
818 struct CloseP pcl;
819 pcl.level = restorestack(L, level); pcl.status = status;
820 status = luaD_rawrunprotected(L, &closepaux, &pcl);
821 if (likely(status == LUA_OK)) /* no more errors? */
822 return pcl.status;
823 else { /* an error occurred; restore saved state and repeat */
824 L->ci = old_ci;
825 L->allowhook = old_allowhooks;
826 }
827 }
828}
829
830
831/*
773** Call the C function 'func' in protected mode, restoring basic 832** Call the C function 'func' in protected mode, restoring basic
774** thread information ('allowhook', etc.) and in particular 833** thread information ('allowhook', etc.) and in particular
775** its stack level in case of errors. 834** its stack level in case of errors.
@@ -783,12 +842,10 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u,
783 L->errfunc = ef; 842 L->errfunc = ef;
784 status = luaD_rawrunprotected(L, func, u); 843 status = luaD_rawrunprotected(L, func, u);
785 if (unlikely(status != LUA_OK)) { /* an error occurred? */ 844 if (unlikely(status != LUA_OK)) { /* an error occurred? */
786 StkId oldtop = restorestack(L, old_top);
787 L->ci = old_ci; 845 L->ci = old_ci;
788 L->allowhook = old_allowhooks; 846 L->allowhook = old_allowhooks;
789 status = luaF_close(L, oldtop, status); 847 status = luaD_closeprotected(L, old_top, status);
790 oldtop = restorestack(L, old_top); /* previous call may change stack */ 848 luaD_seterrorobj(L, status, restorestack(L, old_top));
791 luaD_seterrorobj(L, status, oldtop);
792 luaD_shrinkstack(L); /* restore stack size in case of overflow */ 849 luaD_shrinkstack(L); /* restore stack size in case of overflow */
793 } 850 }
794 L->errfunc = old_errfunc; 851 L->errfunc = old_errfunc;