aboutsummaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldo.c')
-rw-r--r--ldo.c59
1 files changed, 47 insertions, 12 deletions
diff --git a/ldo.c b/ldo.c
index 4b55c31c..59391f7b 100644
--- a/ldo.c
+++ b/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(errcode >= LUA_ERRRUN); /* 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,7 +119,7 @@ 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 = luaD_closeprotected(L, 0, errcode); /* close all upvalues */
122 L->status = cast_byte(errcode); /* mark it as dead */ 123 L->status = cast_byte(errcode); /* mark it as dead */
123 if (g->mainthread->errorJmp) { /* main thread has a handler? */ 124 if (g->mainthread->errorJmp) { /* main thread has a handler? */
124 setobjs2s(L, g->mainthread->top++, L->top - 1); /* copy error obj. */ 125 setobjs2s(L, g->mainthread->top++, L->top - 1); /* copy error obj. */
@@ -409,7 +410,7 @@ static void moveresults (lua_State *L, StkId res, int nres, int wanted) {
409 default: /* multiple results (or to-be-closed variables) */ 410 default: /* multiple results (or to-be-closed variables) */
410 if (hastocloseCfunc(wanted)) { /* to-be-closed variables? */ 411 if (hastocloseCfunc(wanted)) { /* to-be-closed variables? */
411 ptrdiff_t savedres = savestack(L, res); 412 ptrdiff_t savedres = savestack(L, res);
412 luaF_close(L, res, LUA_OK); /* may change the stack */ 413 luaF_close(L, res, CLOSEKTOP); /* may change the stack */
413 res = restorestack(L, savedres); 414 res = restorestack(L, savedres);
414 wanted = codeNresults(wanted); /* correct value */ 415 wanted = codeNresults(wanted); /* correct value */
415 if (wanted == LUA_MULTRET) 416 if (wanted == LUA_MULTRET)
@@ -636,16 +637,13 @@ static CallInfo *findpcall (lua_State *L) {
636** 'luaD_pcall'. If there is no recover point, returns zero. 637** 'luaD_pcall'. If there is no recover point, returns zero.
637*/ 638*/
638static int recover (lua_State *L, int status) { 639static int recover (lua_State *L, int status) {
639 StkId oldtop;
640 CallInfo *ci = findpcall(L); 640 CallInfo *ci = findpcall(L);
641 if (ci == NULL) return 0; /* no recovery point */ 641 if (ci == NULL) return 0; /* no recovery point */
642 /* "finish" luaD_pcall */ 642 /* "finish" luaD_pcall */
643 oldtop = restorestack(L, ci->u2.funcidx);
644 L->ci = ci; 643 L->ci = ci;
645 L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */ 644 L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */
646 status = luaF_close(L, oldtop, status); /* may change the stack */ 645 status = luaD_closeprotected(L, ci->u2.funcidx, status);
647 oldtop = restorestack(L, ci->u2.funcidx); 646 luaD_seterrorobj(L, status, restorestack(L, ci->u2.funcidx));
648 luaD_seterrorobj(L, status, oldtop);
649 luaD_shrinkstack(L); /* restore stack size in case of overflow */ 647 luaD_shrinkstack(L); /* restore stack size in case of overflow */
650 L->errfunc = ci->u.c.old_errfunc; 648 L->errfunc = ci->u.c.old_errfunc;
651 return 1; /* continue running the coroutine */ 649 return 1; /* continue running the coroutine */
@@ -770,6 +768,45 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, lua_KContext ctx,
770 768
771 769
772/* 770/*
771** Auxiliary structure to call 'luaF_close' in protected mode.
772*/
773struct CloseP {
774 StkId level;
775 int status;
776};
777
778
779/*
780** Auxiliary function to call 'luaF_close' in protected mode.
781*/
782static void closepaux (lua_State *L, void *ud) {
783 struct CloseP *pcl = cast(struct CloseP *, ud);
784 luaF_close(L, pcl->level, pcl->status);
785}
786
787
788/*
789** Calls 'luaF_close' in protected mode. Return the original status
790** or, in case of errors, the new status.
791*/
792int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status) {
793 CallInfo *old_ci = L->ci;
794 lu_byte old_allowhooks = L->allowhook;
795 for (;;) { /* keep closing upvalues until no more errors */
796 struct CloseP pcl;
797 pcl.level = restorestack(L, level); pcl.status = status;
798 status = luaD_rawrunprotected(L, &closepaux, &pcl);
799 if (likely(status == LUA_OK)) /* no more errors? */
800 return pcl.status;
801 else { /* an error occurred; restore saved state and repeat */
802 L->ci = old_ci;
803 L->allowhook = old_allowhooks;
804 }
805 }
806}
807
808
809/*
773** Call the C function 'func' in protected mode, restoring basic 810** Call the C function 'func' in protected mode, restoring basic
774** thread information ('allowhook', etc.) and in particular 811** thread information ('allowhook', etc.) and in particular
775** its stack level in case of errors. 812** its stack level in case of errors.
@@ -783,12 +820,10 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u,
783 L->errfunc = ef; 820 L->errfunc = ef;
784 status = luaD_rawrunprotected(L, func, u); 821 status = luaD_rawrunprotected(L, func, u);
785 if (unlikely(status != LUA_OK)) { /* an error occurred? */ 822 if (unlikely(status != LUA_OK)) { /* an error occurred? */
786 StkId oldtop = restorestack(L, old_top);
787 L->ci = old_ci; 823 L->ci = old_ci;
788 L->allowhook = old_allowhooks; 824 L->allowhook = old_allowhooks;
789 status = luaF_close(L, oldtop, status); 825 status = luaD_closeprotected(L, old_top, status);
790 oldtop = restorestack(L, old_top); /* previous call may change stack */ 826 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 */ 827 luaD_shrinkstack(L); /* restore stack size in case of overflow */
793 } 828 }
794 L->errfunc = old_errfunc; 829 L->errfunc = old_errfunc;