From e04f7ed4509af1577c10ead8e5d7d55c65754bf8 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 18 Dec 2001 18:52:30 -0200 Subject: [PATCH] first version of Lua "stackless" --- lapi.c | 4 +--- ldebug.c | 40 ++++++++++++++++------------------------ ldo.h | 7 +++++-- lgc.c | 3 +-- lobject.h | 14 -------------- lstate.c | 5 +++-- lstate.h | 22 +++++++++++++++++++++- luadebug.h | 4 ++-- 8 files changed, 49 insertions(+), 50 deletions(-) diff --git a/lapi.c b/lapi.c index 50578513..07f2cfb2 100644 --- a/lapi.c +++ b/lapi.c @@ -517,9 +517,7 @@ LUA_API void lua_rawcall (lua_State *L, int nargs, int nresults) { lua_lock(L); api_checknelems(L, nargs+1); func = L->top - (nargs+1); - luaD_call(L, func); - if (nresults != LUA_MULTRET) - luaD_adjusttop(L, func + nresults); + luaD_call(L, func, nresults); lua_unlock(L); } diff --git a/ldebug.c b/ldebug.c index 410bbbbf..16a3c5c5 100644 --- a/ldebug.c +++ b/ldebug.c @@ -31,8 +31,7 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, static int isLmark (CallInfo *ci) { - lua_assert(ci == NULL || ttype(ci->base - 1) == LUA_TFUNCTION); - return (ci && ci->prev && !ci_func(ci)->c.isC); + return (ttype(ci->base - 1) == LUA_TFUNCTION && !ci_func(ci)->c.isC); } @@ -58,23 +57,17 @@ LUA_API lua_Hook lua_setlinehook (lua_State *L, lua_Hook func) { static CallInfo *ci_stack (lua_State *L, StkId obj) { CallInfo *ci = L->ci; - while (ci->base > obj) ci = ci->prev; - return (ci != &L->basefunc) ? ci : NULL; + while (ci->base > obj) ci--; + return ci; } LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { - CallInfo *ci; int status; lua_lock(L); - ci = L->ci; - while (level-- && ci != &L->basefunc) { - lua_assert(ci->base > ci->prev->base); - ci = ci->prev; - } - if (ci == &L->basefunc) status = 0; /* there is no such level */ + if (L->ci - L->base_ci <= level) status = 0; /* there is no such level */ else { - ar->_ci = ci; + ar->_ci = (L->ci - L->base_ci) - level; status = 1; } lua_unlock(L); @@ -84,8 +77,7 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) { int refi; - if (lineinfo == NULL || pc == -1) - return -1; /* no line info or function is not active */ + if (lineinfo == NULL) return -1; /* no line info */ refi = prefi ? *prefi : 0; if (lineinfo[refi] < 0) refline += -lineinfo[refi++]; @@ -115,10 +107,11 @@ int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) { static int currentpc (CallInfo *ci) { lua_assert(isLmark(ci)); - if (ci->pc) + if (ci->savedpc) + return (ci->savedpc - ci_func(ci)->l.p->code) - 1; + else if (ci->pc) return (*ci->pc - ci_func(ci)->l.p->code) - 1; - else - return -1; /* function is not active */ + else return 0; } @@ -144,7 +137,7 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { Proto *fp; lua_lock(L); name = NULL; - ci = ar->_ci; + ci = L->base_ci + ar->_ci; fp = getluaproto(ci); if (fp) { /* is a Lua function? */ name = luaF_getlocalname(fp, n, currentpc(ci)); @@ -162,7 +155,7 @@ LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { Proto *fp; lua_lock(L); name = NULL; - ci = ar->_ci; + ci = L->base_ci + ar->_ci; fp = getluaproto(ci); L->top--; /* pop new value */ if (fp) { /* is a Lua function? */ @@ -231,7 +224,7 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { int status = 1; lua_lock(L); if (*what != '>') { /* function is active? */ - ci = ar->_ci; + ci = L->base_ci + ar->_ci; f = ci->base - 1; } else { @@ -246,7 +239,7 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { break; } case 'l': { - ar->currentline = currentline(ci); + ar->currentline = (ci) ? currentline(ci) : -1; break; } case 'u': { @@ -495,14 +488,13 @@ static const char *getobjname (lua_State *L, StkId obj, const char **name) { static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { - ci = ci->prev; /* calling function */ - if (ci == &L->basefunc || !isLmark(ci)) + ci--; /* calling function */ + if (ci == L->base_ci || !isLmark(ci)) return NULL; /* not an active Lua function */ else { Proto *p = ci_func(ci)->l.p; int pc = currentpc(ci); Instruction i; - if (pc == -1) return NULL; /* function is not activated */ i = p->code[pc]; return (GET_OPCODE(i) == OP_CALL ? getobjname(L, ci->base+GETARG_A(i), name) diff --git a/ldo.h b/ldo.h index efb5db07..100bc3d1 100644 --- a/ldo.h +++ b/ldo.h @@ -1,5 +1,5 @@ /* -** $Id: ldo.h,v 1.34 2001/06/08 19:00:57 roberto Exp $ +** $Id: ldo.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -25,7 +25,10 @@ void luaD_init (lua_State *L, int stacksize); void luaD_adjusttop (lua_State *L, StkId newtop); void luaD_lineHook (lua_State *L, int line, lua_Hook linehook); -void luaD_call (lua_State *L, StkId func); +void luaD_callHook (lua_State *L, lua_Hook callhook, const char *event); +StkId luaD_precall (lua_State *L, StkId func); +void luaD_call (lua_State *L, StkId func, int nResults); +void luaD_poscall (lua_State *L, int wanted, StkId firstResult); void luaD_stackerror (lua_State *L); void luaD_error (lua_State *L, const char *s); diff --git a/lgc.c b/lgc.c index 1be57f2a..d7971346 100644 --- a/lgc.c +++ b/lgc.c @@ -363,8 +363,7 @@ static void do1gcTM (lua_State *L, Udata *udata) { setobj(top, tm); setuvalue(top+1, udata); L->top += 2; - luaD_call(L, top); - L->top = top; /* restore top */ + luaD_call(L, top, 0); } } diff --git a/lobject.h b/lobject.h index 9d197af2..a8dcf35e 100644 --- a/lobject.h +++ b/lobject.h @@ -248,20 +248,6 @@ typedef struct Table { #define sizenode(t) (twoto((t)->lsizenode)) #define sizearray(t) ((t)->sizearray) -/* -** informations about a call (for debugging) -*/ -typedef struct CallInfo { - struct CallInfo *prev; /* linked list */ - StkId base; /* base for called function */ - const Instruction **pc; /* current pc of called function */ - int lastpc; /* last pc traced */ - int line; /* current line */ - int refi; /* current index in `lineinfo' */ -} CallInfo; - -#define ci_func(ci) (clvalue((ci)->base - 1)) - extern const TObject luaO_nilobject; diff --git a/lstate.c b/lstate.c index 6f66df93..504313d6 100644 --- a/lstate.c +++ b/lstate.c @@ -87,12 +87,12 @@ LUA_API lua_State *lua_newthread (lua_State *OL, int stacksize) { L->_G = NULL; L->stack = NULL; L->stacksize = 0; - L->ci = &L->basefunc; - L->basefunc.prev = NULL; L->errorJmp = NULL; L->callhook = NULL; L->linehook = NULL; L->openupval = NULL; + L->size_ci = 0; + L->base_ci = NULL; L->allowhooks = 1; L->next = L->previous = L; so.stacksize = stacksize; @@ -130,6 +130,7 @@ static void close_state (lua_State *L, lua_State *OL) { luaM_freearray(L, G(L)->Mbuffer, G(L)->Mbuffsize, char); luaM_freelem(NULL, L->_G); } + luaM_freearray(OL, L->base_ci, L->size_ci, CallInfo); luaM_freearray(OL, L->stack, L->stacksize, TObject); luaM_freelem(OL, L); } diff --git a/lstate.h b/lstate.h index 158f7f8a..150bc4db 100644 --- a/lstate.h +++ b/lstate.h @@ -69,6 +69,24 @@ typedef struct stringtable { } stringtable; +/* +** informations about a call +*/ +typedef struct CallInfo { + StkId base; /* base for called function */ + const Instruction *savedpc; + lua_Hook linehook; + /* extra information for debugging */ + const Instruction **pc; + int lastpc; /* last pc traced */ + int line; /* current line */ + int refi; /* current index in `lineinfo' */ +} CallInfo; + +#define ci_func(ci) (clvalue((ci)->base - 1)) + + + /* ** `global state', shared by all threads of this state */ @@ -98,6 +116,9 @@ struct lua_State { StkId stack_last; /* last free slot in the stack */ StkId stack; /* stack base */ int stacksize; + CallInfo *end_ci; /* points after end of ci array*/ + CallInfo *base_ci; /* array of CallInfo's */ + int size_ci; /* size of array `base_ci' */ global_State *_G; lua_Hook callhook; lua_Hook linehook; @@ -106,7 +127,6 @@ struct lua_State { UpVal *openupval; /* list of open upvalues in this stack */ lua_State *next; /* circular double linked list of states */ lua_State *previous; - CallInfo basefunc; }; diff --git a/luadebug.h b/luadebug.h index b6d7c4b5..d2988506 100644 --- a/luadebug.h +++ b/luadebug.h @@ -1,5 +1,5 @@ /* -** $Id: luadebug.h,v 1.20 2001/04/06 21:17:37 roberto Exp $ +** $Id: luadebug.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $ ** Debugging API ** See Copyright Notice in lua.h */ @@ -39,7 +39,7 @@ struct lua_Debug { const char *source; /* (S) */ char short_src[LUA_IDSIZE]; /* (S) */ /* private part */ - struct CallInfo *_ci; /* active function */ + int _ci; /* active function */ };