lua

A copy of the Lua development repository
Log | Files | Refs | README

commit 93bf6185048256a5df05986460f233ee65136731
parent dfe2f1eeff07b0fc42f6a4255624e704d9c9beb5
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date:   Tue, 15 Aug 2006 16:58:57 -0300

BUG: there is only one C stack, so nCcalls must be global

Diffstat:
Mldo.c | 30+++++++++++++++++++-----------
Mlparser.c | 11++++++-----
Mlstate.c | 7++++---
Mlstate.h | 5+++--
4 files changed, 32 insertions(+), 21 deletions(-)

diff --git a/ldo.c b/ldo.c @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 2.38 2006/06/05 19:36:14 roberto Exp roberto $ +** $Id: ldo.c,v 2.39 2006/07/11 15:53:29 roberto Exp roberto $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -83,7 +83,6 @@ static void resetstack (lua_State *L, int status) { L->base = L->ci->base; luaF_close(L, L->base); /* close possible pending closures */ luaD_seterrorobj(L, status, L->base); - L->nCcalls = 0; L->allowhook = 1; restore_stack_limit(L); L->errfunc = 0; @@ -109,6 +108,7 @@ void luaD_throw (lua_State *L, int errcode) { int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { + unsigned short oldnCcalls = G(L)->nCcalls; struct lua_longjmp lj; lj.status = 0; lj.previous = L->errorJmp; /* chain new error handler */ @@ -117,6 +117,7 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { (*f)(L, ud); ); L->errorJmp = lj.previous; /* restore old error handler */ + G(L)->nCcalls = oldnCcalls; return lj.status; } @@ -369,15 +370,17 @@ int luaD_poscall (lua_State *L, StkId firstResult) { ** function position. */ void luaD_call (lua_State *L, StkId func, int nResults) { - if (++L->nCcalls >= LUAI_MAXCCALLS) { - if (L->nCcalls == LUAI_MAXCCALLS) + global_State *g = G(L); + lua_assert(g->nCcalls >= L->baseCcalls); + if (++g->nCcalls >= LUAI_MAXCCALLS) { + if (g->nCcalls == LUAI_MAXCCALLS) luaG_runerror(L, "C stack overflow"); - else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) + else if (g->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ } if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */ luaV_execute(L, 1); /* call it */ - L->nCcalls--; + g->nCcalls--; luaC_checkGC(L); } @@ -426,15 +429,22 @@ LUA_API int lua_resume (lua_State *L, int nargs) { return resume_error(L, "cannot resume non-suspended coroutine"); } luai_userstateresume(L, nargs); - lua_assert(L->errfunc == 0 && L->nCcalls == 0); + lua_assert(L->errfunc == 0 && L->baseCcalls == 0); + if (G(L)->nCcalls >= LUAI_MAXCCALLS) + return resume_error(L, "C stack overflow"); + L->baseCcalls = ++G(L)->nCcalls; status = luaD_rawrunprotected(L, resume, L->top - nargs); if (status != 0) { /* error? */ L->status = cast_byte(status); /* mark thread as `dead' */ luaD_seterrorobj(L, status, L->top); L->ci->top = L->top; } - else + else { + lua_assert(L->baseCcalls == G(L)->nCcalls); status = L->status; + } + --G(L)->nCcalls; + L->baseCcalls = 0; lua_unlock(L); return status; } @@ -443,7 +453,7 @@ LUA_API int lua_resume (lua_State *L, int nargs) { LUA_API int lua_yield (lua_State *L, int nresults) { luai_userstateyield(L, nresults); lua_lock(L); - if (L->nCcalls > 0) + if (G(L)->nCcalls > L->baseCcalls) luaG_runerror(L, "attempt to yield across metamethod/C-call boundary"); L->base = L->top - nresults; /* protect stack slots below */ L->status = LUA_YIELD; @@ -455,7 +465,6 @@ LUA_API int lua_yield (lua_State *L, int nresults) { int luaD_pcall (lua_State *L, Pfunc func, void *u, ptrdiff_t old_top, ptrdiff_t ef) { int status; - unsigned short oldnCcalls = L->nCcalls; ptrdiff_t old_ci = saveci(L, L->ci); lu_byte old_allowhooks = L->allowhook; ptrdiff_t old_errfunc = L->errfunc; @@ -465,7 +474,6 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u, StkId oldtop = restorestack(L, old_top); luaF_close(L, oldtop); /* close possible pending closures */ luaD_seterrorobj(L, status, oldtop); - L->nCcalls = oldnCcalls; L->ci = restoreci(L, old_ci); L->base = L->ci->base; L->savedpc = L->ci->savedpc; diff --git a/lparser.c b/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 2.44 2006/07/11 15:53:29 roberto Exp roberto $ +** $Id: lparser.c,v 2.45 2006/07/12 19:02:50 roberto Exp roberto $ ** Lua Parser ** See Copyright Notice in lua.h */ @@ -73,7 +73,7 @@ static void errorlimit (FuncState *fs, int limit, const char *what) { luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) : luaO_pushfstring(fs->L, "function at line %d has more than %d %s", fs->f->linedefined, limit, what); - luaX_lexerror(fs->ls, msg, 0); + luaX_lexerror(fs->ls, msg, fs->ls->t.token); } @@ -274,12 +274,13 @@ static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { static void enterlevel (LexState *ls) { - ++ls->L->nCcalls; - luaY_checklimit(ls->fs, ls->L->nCcalls, LUAI_MAXCCALLS, "syntax levels"); + global_State *g = G(ls->L); + ++g->nCcalls; + luaY_checklimit(ls->fs, g->nCcalls, LUAI_MAXCCALLS, "syntax levels"); } -#define leavelevel(ls) ((ls)->L->nCcalls--) +#define leavelevel(ls) (G((ls)->L)->nCcalls--) static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) { diff --git a/lstate.c b/lstate.c @@ -1,5 +1,5 @@ /* -** $Id: lstate.c,v 2.36 2006/05/24 14:15:50 roberto Exp roberto $ +** $Id: lstate.c,v 2.37 2006/07/11 15:53:29 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -94,7 +94,7 @@ static void preinit_state (lua_State *L, global_State *g) { resethookcount(L); L->openupval = NULL; L->size_ci = 0; - L->nCcalls = 0; + L->baseCcalls = 0; L->status = 0; L->base_ci = L->ci = NULL; L->savedpc = NULL; @@ -161,6 +161,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); L->marked = luaC_white(g); g->emergencygc = 0; + g->nCcalls = 0; set2bits(L->marked, FIXEDBIT, SFIXEDBIT); preinit_state(L, g); g->frealloc = f; @@ -214,7 +215,7 @@ LUA_API void lua_close (lua_State *L) { do { /* repeat until no more errors */ L->ci = L->base_ci; L->base = L->top = L->ci->base; - L->nCcalls = 0; + G(L)->nCcalls = 0; } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0); lua_assert(G(L)->tmudata == NULL); luai_userstateclose(L); diff --git a/lstate.h b/lstate.h @@ -1,5 +1,5 @@ /* -** $Id: lstate.h,v 2.24 2006/02/06 18:27:59 roberto Exp roberto $ +** $Id: lstate.h,v 2.25 2006/07/11 15:53:29 roberto Exp $ ** Global State ** See Copyright Notice in lua.h */ @@ -69,6 +69,7 @@ typedef struct global_State { stringtable strt; /* hash table for strings */ lua_Alloc frealloc; /* function to reallocate memory */ void *ud; /* auxiliary data to `frealloc' */ + unsigned short nCcalls; /* number of nested C calls */ lu_byte currentwhite; lu_byte gcstate; /* state of garbage collector */ lu_byte emergencygc; /* true when collect was trigged by alloc error */ @@ -112,7 +113,7 @@ struct lua_State { CallInfo *base_ci; /* array of CallInfo's */ int stacksize; int size_ci; /* size of array `base_ci' */ - unsigned short nCcalls; /* number of nested C calls */ + unsigned short baseCcalls; /* number of nested C calls when resuming */ lu_byte hookmask; lu_byte allowhook; int basehookcount;