mirror of
https://github.com/lua/lua
synced 2024-11-26 06:39:41 +03:00
BUG: there is only one C stack, so nCcalls must be global
This commit is contained in:
parent
dfe2f1eeff
commit
93bf618504
30
ldo.c
30
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
|
** Stack and Call structure of Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -83,7 +83,6 @@ static void resetstack (lua_State *L, int status) {
|
|||||||
L->base = L->ci->base;
|
L->base = L->ci->base;
|
||||||
luaF_close(L, L->base); /* close possible pending closures */
|
luaF_close(L, L->base); /* close possible pending closures */
|
||||||
luaD_seterrorobj(L, status, L->base);
|
luaD_seterrorobj(L, status, L->base);
|
||||||
L->nCcalls = 0;
|
|
||||||
L->allowhook = 1;
|
L->allowhook = 1;
|
||||||
restore_stack_limit(L);
|
restore_stack_limit(L);
|
||||||
L->errfunc = 0;
|
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) {
|
int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
|
||||||
|
unsigned short oldnCcalls = G(L)->nCcalls;
|
||||||
struct lua_longjmp lj;
|
struct lua_longjmp lj;
|
||||||
lj.status = 0;
|
lj.status = 0;
|
||||||
lj.previous = L->errorJmp; /* chain new error handler */
|
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);
|
(*f)(L, ud);
|
||||||
);
|
);
|
||||||
L->errorJmp = lj.previous; /* restore old error handler */
|
L->errorJmp = lj.previous; /* restore old error handler */
|
||||||
|
G(L)->nCcalls = oldnCcalls;
|
||||||
return lj.status;
|
return lj.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,15 +370,17 @@ int luaD_poscall (lua_State *L, StkId firstResult) {
|
|||||||
** function position.
|
** function position.
|
||||||
*/
|
*/
|
||||||
void luaD_call (lua_State *L, StkId func, int nResults) {
|
void luaD_call (lua_State *L, StkId func, int nResults) {
|
||||||
if (++L->nCcalls >= LUAI_MAXCCALLS) {
|
global_State *g = G(L);
|
||||||
if (L->nCcalls == LUAI_MAXCCALLS)
|
lua_assert(g->nCcalls >= L->baseCcalls);
|
||||||
|
if (++g->nCcalls >= LUAI_MAXCCALLS) {
|
||||||
|
if (g->nCcalls == LUAI_MAXCCALLS)
|
||||||
luaG_runerror(L, "C stack overflow");
|
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 */
|
luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
|
||||||
}
|
}
|
||||||
if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */
|
if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */
|
||||||
luaV_execute(L, 1); /* call it */
|
luaV_execute(L, 1); /* call it */
|
||||||
L->nCcalls--;
|
g->nCcalls--;
|
||||||
luaC_checkGC(L);
|
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");
|
return resume_error(L, "cannot resume non-suspended coroutine");
|
||||||
}
|
}
|
||||||
luai_userstateresume(L, nargs);
|
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);
|
status = luaD_rawrunprotected(L, resume, L->top - nargs);
|
||||||
if (status != 0) { /* error? */
|
if (status != 0) { /* error? */
|
||||||
L->status = cast_byte(status); /* mark thread as `dead' */
|
L->status = cast_byte(status); /* mark thread as `dead' */
|
||||||
luaD_seterrorobj(L, status, L->top);
|
luaD_seterrorobj(L, status, L->top);
|
||||||
L->ci->top = L->top;
|
L->ci->top = L->top;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
|
lua_assert(L->baseCcalls == G(L)->nCcalls);
|
||||||
status = L->status;
|
status = L->status;
|
||||||
|
}
|
||||||
|
--G(L)->nCcalls;
|
||||||
|
L->baseCcalls = 0;
|
||||||
lua_unlock(L);
|
lua_unlock(L);
|
||||||
return status;
|
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) {
|
LUA_API int lua_yield (lua_State *L, int nresults) {
|
||||||
luai_userstateyield(L, nresults);
|
luai_userstateyield(L, nresults);
|
||||||
lua_lock(L);
|
lua_lock(L);
|
||||||
if (L->nCcalls > 0)
|
if (G(L)->nCcalls > L->baseCcalls)
|
||||||
luaG_runerror(L, "attempt to yield across metamethod/C-call boundary");
|
luaG_runerror(L, "attempt to yield across metamethod/C-call boundary");
|
||||||
L->base = L->top - nresults; /* protect stack slots below */
|
L->base = L->top - nresults; /* protect stack slots below */
|
||||||
L->status = LUA_YIELD;
|
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,
|
int luaD_pcall (lua_State *L, Pfunc func, void *u,
|
||||||
ptrdiff_t old_top, ptrdiff_t ef) {
|
ptrdiff_t old_top, ptrdiff_t ef) {
|
||||||
int status;
|
int status;
|
||||||
unsigned short oldnCcalls = L->nCcalls;
|
|
||||||
ptrdiff_t old_ci = saveci(L, L->ci);
|
ptrdiff_t old_ci = saveci(L, L->ci);
|
||||||
lu_byte old_allowhooks = L->allowhook;
|
lu_byte old_allowhooks = L->allowhook;
|
||||||
ptrdiff_t old_errfunc = L->errfunc;
|
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);
|
StkId oldtop = restorestack(L, old_top);
|
||||||
luaF_close(L, oldtop); /* close possible pending closures */
|
luaF_close(L, oldtop); /* close possible pending closures */
|
||||||
luaD_seterrorobj(L, status, oldtop);
|
luaD_seterrorobj(L, status, oldtop);
|
||||||
L->nCcalls = oldnCcalls;
|
|
||||||
L->ci = restoreci(L, old_ci);
|
L->ci = restoreci(L, old_ci);
|
||||||
L->base = L->ci->base;
|
L->base = L->ci->base;
|
||||||
L->savedpc = L->ci->savedpc;
|
L->savedpc = L->ci->savedpc;
|
||||||
|
11
lparser.c
11
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
|
** Lua Parser
|
||||||
** See Copyright Notice in lua.h
|
** 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, "main function has more than %d %s", limit, what) :
|
||||||
luaO_pushfstring(fs->L, "function at line %d has more than %d %s",
|
luaO_pushfstring(fs->L, "function at line %d has more than %d %s",
|
||||||
fs->f->linedefined, limit, what);
|
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) {
|
static void enterlevel (LexState *ls) {
|
||||||
++ls->L->nCcalls;
|
global_State *g = G(ls->L);
|
||||||
luaY_checklimit(ls->fs, ls->L->nCcalls, LUAI_MAXCCALLS, "syntax levels");
|
++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) {
|
static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) {
|
||||||
|
7
lstate.c
7
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
|
** Global State
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -94,7 +94,7 @@ static void preinit_state (lua_State *L, global_State *g) {
|
|||||||
resethookcount(L);
|
resethookcount(L);
|
||||||
L->openupval = NULL;
|
L->openupval = NULL;
|
||||||
L->size_ci = 0;
|
L->size_ci = 0;
|
||||||
L->nCcalls = 0;
|
L->baseCcalls = 0;
|
||||||
L->status = 0;
|
L->status = 0;
|
||||||
L->base_ci = L->ci = NULL;
|
L->base_ci = L->ci = NULL;
|
||||||
L->savedpc = NULL;
|
L->savedpc = NULL;
|
||||||
@ -161,6 +161,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
|
|||||||
g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
|
g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
|
||||||
L->marked = luaC_white(g);
|
L->marked = luaC_white(g);
|
||||||
g->emergencygc = 0;
|
g->emergencygc = 0;
|
||||||
|
g->nCcalls = 0;
|
||||||
set2bits(L->marked, FIXEDBIT, SFIXEDBIT);
|
set2bits(L->marked, FIXEDBIT, SFIXEDBIT);
|
||||||
preinit_state(L, g);
|
preinit_state(L, g);
|
||||||
g->frealloc = f;
|
g->frealloc = f;
|
||||||
@ -214,7 +215,7 @@ LUA_API void lua_close (lua_State *L) {
|
|||||||
do { /* repeat until no more errors */
|
do { /* repeat until no more errors */
|
||||||
L->ci = L->base_ci;
|
L->ci = L->base_ci;
|
||||||
L->base = L->top = L->ci->base;
|
L->base = L->top = L->ci->base;
|
||||||
L->nCcalls = 0;
|
G(L)->nCcalls = 0;
|
||||||
} while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0);
|
} while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0);
|
||||||
lua_assert(G(L)->tmudata == NULL);
|
lua_assert(G(L)->tmudata == NULL);
|
||||||
luai_userstateclose(L);
|
luai_userstateclose(L);
|
||||||
|
5
lstate.h
5
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
|
** Global State
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -69,6 +69,7 @@ typedef struct global_State {
|
|||||||
stringtable strt; /* hash table for strings */
|
stringtable strt; /* hash table for strings */
|
||||||
lua_Alloc frealloc; /* function to reallocate memory */
|
lua_Alloc frealloc; /* function to reallocate memory */
|
||||||
void *ud; /* auxiliary data to `frealloc' */
|
void *ud; /* auxiliary data to `frealloc' */
|
||||||
|
unsigned short nCcalls; /* number of nested C calls */
|
||||||
lu_byte currentwhite;
|
lu_byte currentwhite;
|
||||||
lu_byte gcstate; /* state of garbage collector */
|
lu_byte gcstate; /* state of garbage collector */
|
||||||
lu_byte emergencygc; /* true when collect was trigged by alloc error */
|
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 */
|
CallInfo *base_ci; /* array of CallInfo's */
|
||||||
int stacksize;
|
int stacksize;
|
||||||
int size_ci; /* size of array `base_ci' */
|
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 hookmask;
|
||||||
lu_byte allowhook;
|
lu_byte allowhook;
|
||||||
int basehookcount;
|
int basehookcount;
|
||||||
|
Loading…
Reference in New Issue
Block a user