From fe237ad8085f34e89fcd3610a9771215af63f03f Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 1 Dec 1999 17:50:08 -0200 Subject: fixed stack; first version. --- lapi.c | 103 +++++++++--------- lbuiltin.c | 99 ++++++++--------- ldo.c | 171 +++++++++++++++--------------- ldo.h | 18 ++-- lgc.c | 8 +- lparser.c | 8 +- lstate.c | 7 +- lstate.h | 27 ++--- lvm.c | 351 +++++++++++++++++++++++++++++++------------------------------ lvm.h | 10 +- 10 files changed, 400 insertions(+), 402 deletions(-) diff --git a/lapi.c b/lapi.c index 50355b06..364179a4 100644 --- a/lapi.c +++ b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 1.59 1999/11/29 19:11:36 roberto Exp roberto $ +** $Id: lapi.c,v 1.60 1999/11/29 19:31:29 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -63,28 +63,28 @@ static const TObject *luaA_protovalue (const TObject *o) { static void checkCparams (lua_State *L, int nParams) { - if (L->stack.top-L->stack.stack < L->Cstack.base+nParams) + if (nParams > L->top-L->Cstack.base) lua_error(L, "API error - wrong number of arguments in C2lua stack"); } static lua_Object put_luaObject (lua_State *L, const TObject *o) { - luaD_openstack(L, (L->stack.top-L->stack.stack)-L->Cstack.base); - L->stack.stack[L->Cstack.base++] = *o; - return L->Cstack.base; /* this is +1 real position (see Ref) */ + luaD_openstack(L, L->Cstack.base); + *L->Cstack.base++ = *o; + return Ref(L, L->Cstack.base-1); } lua_Object luaA_putObjectOnTop (lua_State *L) { - luaD_openstack(L, (L->stack.top-L->stack.stack)-L->Cstack.base); - L->stack.stack[L->Cstack.base++] = *(--L->stack.top); - return L->Cstack.base; /* this is +1 real position (see Ref) */ + luaD_openstack(L, L->Cstack.base); + *L->Cstack.base++ = *(--L->top); + return Ref(L, L->Cstack.base-1); } static void top2LC (lua_State *L, int n) { /* Put the 'n' elements on the top as the Lua2C contents */ - L->Cstack.base = (L->stack.top-L->stack.stack); /* new base */ + L->Cstack.base = L->top; /* new base */ L->Cstack.lua2C = L->Cstack.base-n; /* position of the new results */ L->Cstack.num = n; /* number of results */ } @@ -98,13 +98,11 @@ lua_Object lua_pop (lua_State *L) { /* ** Get a parameter, returning the object handle or LUA_NOOBJECT on error. -** 'number' must be 1 to get the first parameter. +** `number' must be 1 to get the first parameter. */ lua_Object lua_lua2C (lua_State *L, int number) { if (number <= 0 || number > L->Cstack.num) return LUA_NOOBJECT; - /* Ref(L, L->stack.stack+(L->Cstack.lua2C+number-1)) == - L->stack.stack+(L->Cstack.lua2C+number-1)-L->stack.stack+1 == */ - return L->Cstack.lua2C+number; + return Ref(L, L->Cstack.lua2C+number-1); } @@ -112,8 +110,8 @@ int lua_callfunction (lua_State *L, lua_Object function) { if (function == LUA_NOOBJECT) return 1; else { - luaD_openstack(L, (L->stack.top-L->stack.stack)-L->Cstack.base); - set_normalized(L->stack.stack+L->Cstack.base, Address(L, function)); + luaD_openstack(L, L->Cstack.base); + set_normalized(L->Cstack.base, Address(L, function)); return luaD_protectedrun(L); } } @@ -126,7 +124,7 @@ lua_Object lua_gettagmethod (lua_State *L, int tag, const char *event) { lua_Object lua_settagmethod (lua_State *L, int tag, const char *event) { checkCparams(L, 1); - luaT_settagmethod(L, tag, event, L->stack.top-1); + luaT_settagmethod(L, tag, event, L->top-1); return luaA_putObjectOnTop(L); } @@ -149,24 +147,24 @@ lua_Object lua_gettable (lua_State *L) { lua_Object lua_rawgettable (lua_State *L) { checkCparams(L, 2); - if (ttype(L->stack.top-2) != LUA_T_ARRAY) + if (ttype(L->top-2) != LUA_T_ARRAY) lua_error(L, "indexed expression not a table in rawgettable"); - *(L->stack.top-2) = *luaH_get(L, avalue(L->stack.top-2), L->stack.top-1); - --L->stack.top; + *(L->top-2) = *luaH_get(L, avalue(L->top-2), L->top-1); + --L->top; return luaA_putObjectOnTop(L); } void lua_settable (lua_State *L) { checkCparams(L, 3); - luaV_settable(L, L->stack.top-3); - L->stack.top -= 2; /* pop table and index */ + luaV_settable(L, L->top-3); + L->top -= 2; /* pop table and index */ } void lua_rawsettable (lua_State *L) { checkCparams(L, 3); - luaV_rawsettable(L, L->stack.top-3); + luaV_rawsettable(L, L->top-3); } @@ -202,7 +200,7 @@ void lua_setglobal (lua_State *L, const char *name) { void lua_rawsetglobal (lua_State *L, const char *name) { GlobalVar *gv = luaS_assertglobalbyname(L, name); checkCparams(L, 1); - gv->value = *(--L->stack.top); + gv->value = *(--L->top); } @@ -280,19 +278,19 @@ lua_CFunction lua_getcfunction (lua_State *L, lua_Object obj) { void lua_pushnil (lua_State *L) { - ttype(L->stack.top) = LUA_T_NIL; + ttype(L->top) = LUA_T_NIL; incr_top; } void lua_pushnumber (lua_State *L, double n) { - ttype(L->stack.top) = LUA_T_NUMBER; - nvalue(L->stack.top) = n; + ttype(L->top) = LUA_T_NUMBER; + nvalue(L->top) = n; incr_top; } void lua_pushlstring (lua_State *L, const char *s, long len) { - tsvalue(L->stack.top) = luaS_newlstr(L, s, len); - ttype(L->stack.top) = LUA_T_STRING; + tsvalue(L->top) = luaS_newlstr(L, s, len); + ttype(L->top) = LUA_T_STRING; incr_top; luaC_checkGC(L); } @@ -308,8 +306,8 @@ void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { if (fn == NULL) lua_error(L, "API error - attempt to push a NULL Cfunction"); checkCparams(L, n); - ttype(L->stack.top) = LUA_T_CPROTO; - fvalue(L->stack.top) = fn; + ttype(L->top) = LUA_T_CPROTO; + fvalue(L->top) = fn; incr_top; luaV_closure(L, n); luaC_checkGC(L); @@ -318,21 +316,21 @@ void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { void lua_pushusertag (lua_State *L, void *u, int tag) { if (tag < 0 && tag != LUA_ANYTAG) luaT_realtag(L, tag); /* error if tag is not valid */ - tsvalue(L->stack.top) = luaS_createudata(L, u, tag); - ttype(L->stack.top) = LUA_T_USERDATA; + tsvalue(L->top) = luaS_createudata(L, u, tag); + ttype(L->top) = LUA_T_USERDATA; incr_top; luaC_checkGC(L); } void luaA_pushobject (lua_State *L, const TObject *o) { - *L->stack.top = *o; + *L->top = *o; incr_top; } void lua_pushobject (lua_State *L, lua_Object o) { if (o == LUA_NOOBJECT) lua_error(L, "API error - attempt to push a NOOBJECT"); - set_normalized(L->stack.top, Address(L, o)); + set_normalized(L->top, Address(L, o)); incr_top; } @@ -368,18 +366,18 @@ int lua_tag (lua_State *L, lua_Object lo) { void lua_settag (lua_State *L, int tag) { checkCparams(L, 1); luaT_realtag(L, tag); - switch (ttype(L->stack.top-1)) { + switch (ttype(L->top-1)) { case LUA_T_ARRAY: - (L->stack.top-1)->value.a->htag = tag; + (L->top-1)->value.a->htag = tag; break; case LUA_T_USERDATA: - (L->stack.top-1)->value.ts->u.d.tag = tag; + (L->top-1)->value.ts->u.d.tag = tag; break; default: luaL_verror(L, "cannot change the tag of a %.20s", - luaO_typename(L, L->stack.top-1)); + luaO_typename(L, L->top-1)); } - L->stack.top--; + L->top--; } @@ -395,7 +393,7 @@ GlobalVar *luaA_nextvar (lua_State *L, TaggedString *ts) { while (gv && gv->value.ttype == LUA_T_NIL) /* skip globals with nil */ gv = gv->next; if (gv) { - ttype(L->stack.top) = LUA_T_STRING; tsvalue(L->stack.top) = gv->name; + ttype(L->top) = LUA_T_STRING; tsvalue(L->top) = gv->name; incr_top; luaA_pushobject(L, &gv->value); } @@ -479,12 +477,12 @@ int lua_setdebug (lua_State *L, int debug) { lua_Function lua_stackedfunction (lua_State *L, int level) { - StkId i; - for (i = (L->stack.top-1)-L->stack.stack; i>=0; i--) { - int t = L->stack.stack[i].ttype; + int i; + for (i = (L->top-1)-L->stack; i>=0; i--) { + int t = L->stack[i].ttype; if (t == LUA_T_CLMARK || t == LUA_T_PMARK || t == LUA_T_CMARK) if (level-- == 0) - return Ref(L, L->stack.stack+i); + return Ref(L, L->stack+i); } return LUA_NOOBJECT; } @@ -498,8 +496,7 @@ int lua_nups (lua_State *L, lua_Function func) { int lua_currentline (lua_State *L, lua_Function func) { const TObject *f = Address(L, func); - return (f+1 < L->stack.top && (f+1)->ttype == LUA_T_LINE) ? - (f+1)->value.i : -1; + return (f+1 < L->top && (f+1)->ttype == LUA_T_LINE) ? (f+1)->value.i : -1; } @@ -533,11 +530,11 @@ int lua_setlocal (lua_State *L, lua_Function func, int local_number) { const char *name = luaF_getlocalname(fp, local_number, lua_currentline(L, func)); checkCparams(L, 1); - --L->stack.top; + --L->top; if (name) { /* if "name", there must be a LUA_T_LINE */ /* therefore, f+2 points to function base */ - *((f+2)+(local_number-1)) = *L->stack.top; + *((f+2)+(local_number-1)) = *L->top; return 1; } else @@ -565,14 +562,14 @@ void lua_funcinfo (lua_State *L, lua_Object func, static int checkfunc (lua_State *L, TObject *o) { - return luaO_equalObj(o, L->stack.top); + return luaO_equalObj(o, L->top); } const char *lua_getobjname (lua_State *L, lua_Object o, const char **name) { /* try to find a name for given function */ GlobalVar *g; - set_normalized(L->stack.top, Address(L, o)); /* to be used by `checkfunc' */ + set_normalized(L->top, Address(L, o)); /* to be used by `checkfunc' */ for (g=L->rootglobal; g; g=g->next) { if (checkfunc(L, &g->value)) { *name = g->name->str; @@ -610,7 +607,7 @@ void lua_beginblock (lua_State *L) { void lua_endblock (lua_State *L) { --L->numCblocks; L->Cstack = L->Cblocks[L->numCblocks]; - luaD_adjusttop(L, L->Cstack.base); + L->top = L->Cstack.base; } @@ -618,8 +615,8 @@ void lua_endblock (lua_State *L) { int lua_ref (lua_State *L, int lock) { int ref; checkCparams(L, 1); - ref = luaR_ref(L, L->stack.top-1, lock); - L->stack.top--; + ref = luaR_ref(L, L->top-1, lock); + L->top--; return ref; } diff --git a/lbuiltin.c b/lbuiltin.c index c9fefa35..28b64270 100644 --- a/lbuiltin.c +++ b/lbuiltin.c @@ -1,5 +1,5 @@ /* -** $Id: lbuiltin.c,v 1.77 1999/11/29 19:11:36 roberto Exp roberto $ +** $Id: lbuiltin.c,v 1.78 1999/11/30 13:06:50 roberto Exp roberto $ ** Built-in functions ** See Copyright Notice in lua.h */ @@ -37,8 +37,8 @@ static void pushtagstring (lua_State *L, TaggedString *s) { - ttype(L->stack.top) = LUA_T_STRING; - tsvalue(L->stack.top) = s; + ttype(L->top) = LUA_T_STRING; + tsvalue(L->top) = s; incr_top; } @@ -303,7 +303,7 @@ static void luaB_call (lua_State *L) { /* push arg[1...n] */ luaD_checkstack(L, narg); for (i=0; istack.top++) = *luaH_getint(L, arg, i+1); + *(L->top++) = *luaH_getint(L, arg, i+1); status = lua_callfunction(L, f); if (err != LUA_NOOBJECT) { /* restore old error method */ lua_pushobject(L, err); @@ -319,7 +319,7 @@ static void luaB_call (lua_State *L) { } else { /* no errors */ if (strchr(options, 'p')) { /* pack results? */ - luaV_pack(L, L->Cstack.lua2C, L->Cstack.num, L->stack.top); + luaV_pack(L, L->Cstack.lua2C, L->Cstack.num, L->top); incr_top; } else @@ -414,65 +414,60 @@ static void luaB_assert (lua_State *L) { static void luaB_foreachi (lua_State *L) { - struct Stack *S = &L->stack; const Hash *t = gettable(L, 1); int n = (int)getnarg(L, t); int i; - StkId f = luaA_Address(L, luaL_functionarg(L, 2)) - S->stack; - /* 'f' cannot be a pointer to TObject, because it is on the stack, and the - stack may be reallocated by the call. */ + StkId f = luaA_Address(L, luaL_functionarg(L, 2)); luaD_checkstack(L, 3); /* for f, key, and val */ for (i=1; i<=n; i++) { - *(S->top++) = *(S->stack+f); - ttype(S->top) = LUA_T_NUMBER; nvalue(S->top++) = i; - *(S->top++) = *luaH_getint(L, t, i); - luaD_call(L, S->top-3, 1); - if (ttype(S->top-1) != LUA_T_NIL) + *(L->top++) = *f; + ttype(L->top) = LUA_T_NUMBER; nvalue(L->top++) = i; + *(L->top++) = *luaH_getint(L, t, i); + luaD_call(L, L->top-3, 1); + if (ttype(L->top-1) != LUA_T_NIL) return; - S->top--; + L->top--; } } static void luaB_foreach (lua_State *L) { - struct Stack *S = &L->stack; const Hash *a = gettable(L, 1); - StkId f = luaA_Address(L, luaL_functionarg(L, 2)) - S->stack; + StkId f = luaA_Address(L, luaL_functionarg(L, 2)); int i; luaD_checkstack(L, 3); /* for f, key, and val */ for (i=0; isize; i++) { const Node *nd = &(a->node[i]); if (ttype(val(nd)) != LUA_T_NIL) { - *(S->top++) = *(S->stack+f); - *(S->top++) = *key(nd); - *(S->top++) = *val(nd); - luaD_call(L, S->top-3, 1); - if (ttype(S->top-1) != LUA_T_NIL) + *(L->top++) = *f; + *(L->top++) = *key(nd); + *(L->top++) = *val(nd); + luaD_call(L, L->top-3, 1); + if (ttype(L->top-1) != LUA_T_NIL) return; - S->top--; /* remove result */ + L->top--; /* remove result */ } } } static void luaB_foreachvar (lua_State *L) { - struct Stack *S = &L->stack; - StkId f = luaA_Address(L, luaL_functionarg(L, 1)) - S->stack; + StkId f = luaA_Address(L, luaL_functionarg(L, 1)); GlobalVar *gv; luaD_checkstack(L, 4); /* for extra var name, f, var name, and globalval */ for (gv = L->rootglobal; gv; gv = gv->next) { if (gv->value.ttype != LUA_T_NIL) { pushtagstring(L, gv->name); /* keep (extra) name on stack to avoid GC */ - *(S->top++) = *(S->stack+f); + *(L->top++) = *f; pushtagstring(L, gv->name); - *(S->top++) = gv->value; - luaD_call(L, S->top-3, 1); - if (ttype(S->top-1) != LUA_T_NIL) { - S->top--; - *(S->top-1) = *S->top; /* remove extra name */ + *(L->top++) = gv->value; + luaD_call(L, L->top-3, 1); + if (ttype(L->top-1) != LUA_T_NIL) { + L->top--; + *(L->top-1) = *L->top; /* remove extra name */ return; } - S->top-=2; /* remove result and extra name */ + L->top-=2; /* remove result and extra name */ } } } @@ -530,26 +525,24 @@ static int sort_comp (lua_State *L, lua_Object f, const TObject *a, const TObject *b) { /* notice: the caller (auxsort) must check stack space */ if (f != LUA_NOOBJECT) { - *(L->stack.top) = *luaA_Address(L, f); - *(L->stack.top+1) = *a; - *(L->stack.top+2) = *b; - L->stack.top += 3; - luaD_call(L, L->stack.top-3, 1); + *(L->top) = *luaA_Address(L, f); + *(L->top+1) = *a; + *(L->top+2) = *b; + L->top += 3; + luaD_call(L, L->top-3, 1); } else { /* a < b? */ - *(L->stack.top) = *a; - *(L->stack.top+1) = *b; - L->stack.top += 2; - luaV_comparison(L, LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT); + *(L->top) = *a; + *(L->top+1) = *b; + luaV_comparison(L, L->top+2, LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT); + L->top++; /* result of comparison */ } - return ttype(--(L->stack.top)) != LUA_T_NIL; + return ttype(--(L->top)) != LUA_T_NIL; } static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) { - struct Stack *S = &L->stack; - StkId P = S->top - S->stack; /* temporary place for pivot */ - S->top++; - ttype(S->stack+P) = LUA_T_NIL; + StkId P = L->top++; /* temporary place for pivot */ + ttype(P) = LUA_T_NIL; while (l < u) { /* for tail recursion */ int i, j; /* sort elements a[l], a[(l+u)/2] and a[u] */ @@ -557,22 +550,22 @@ static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) { swap(L, a, l, u); /* a[u]stack+P) = *luaH_getint(L, a, i); /* P = a[i] */ - if (sort_comp(L, f, S->stack+P, luaH_getint(L, a, l))) /* a[i]stack+P)) /* a[u]stack+P) = *luaH_getint(L, a, i); /* save pivot on stack (GC) */ + *P = *luaH_getint(L, a, i); /* save pivot on stack (GC) */ swap(L, a, i, u-1); /* put median element as pivot (a[u-1]) */ /* a[l] <= P == a[u-1] <= a[u], only needs to sort from l+1 to u-2 */ i = l; j = u-1; for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */ /* repeat i++ until a[i] >= P */ - while (sort_comp(L, f, luaH_getint(L, a, ++i), S->stack+P)) + while (sort_comp(L, f, luaH_getint(L, a, ++i), P)) if (i>u) lua_error(L, "invalid order function for sorting"); /* repeat j-- until a[j] <= P */ - while (sort_comp(L, f, (S->stack+P), luaH_getint(L, a, --j))) + while (sort_comp(L, f, P, luaH_getint(L, a, --j))) if (jtop--; /* remove pivot from stack */ + L->top--; /* remove pivot from stack */ } static void luaB_sort (lua_State *L) { diff --git a/ldo.c b/ldo.c index cadfd650..25632e4b 100644 --- a/ldo.c +++ b/ldo.c @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 1.52 1999/11/22 13:12:07 roberto Exp roberto $ +** $Id: ldo.c,v 1.53 1999/11/25 18:58:51 roberto Exp roberto $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -28,39 +28,40 @@ -#ifndef STACK_LIMIT -#define STACK_LIMIT 6000 /* arbitrary limit */ +#ifndef DEFAULT_STACK_SIZE +#define DEFAULT_STACK_SIZE 1024 #endif +#define EXTRA_STACK 32 /* space to handle stack overflow errors */ - -#define STACK_UNIT 128 - - -#ifdef DEBUG -#undef STACK_UNIT -#define STACK_UNIT 2 -#endif +/* +** typical numer of recursive calls that fit in the stack +** (only for error messages) +*/ +#define REC_DEEP (DEFAULT_STACK_SIZE/20) void luaD_init (lua_State *L) { - L->stack.stack = luaM_newvector(L, STACK_UNIT, TObject); - L->stack.top = L->stack.stack; - L->stack.last = L->stack.stack+(STACK_UNIT-1); + L->stack = luaM_newvector(L, DEFAULT_STACK_SIZE+EXTRA_STACK, TObject); + L->stack_last = L->stack+(DEFAULT_STACK_SIZE-1); + L->Cstack.base = L->Cstack.lua2C = L->top = L->stack; + L->Cstack.num = 0; } void luaD_checkstack (lua_State *L, int n) { - struct Stack *S = &L->stack; - if (S->last-S->top <= n) { - StkId top = S->top-S->stack; - int stacksize = (S->last-S->stack)+STACK_UNIT+n; - luaM_reallocvector(L, S->stack, stacksize, TObject); - S->last = S->stack+(stacksize-1); - S->top = S->stack + top; - if (stacksize >= STACK_LIMIT) { /* stack overflow? */ - if (lua_stackedfunction(L, 100) == LUA_NOOBJECT) /* 100 funcs on stack? */ - lua_error(L, "Lua2C - C2Lua overflow"); /* doesn't look like a rec. loop */ + if (L->stack_last-L->top <= n) { /* stack overflow? */ + if (L->stack_last-L->stack > (DEFAULT_STACK_SIZE-1)) { + /* overflow while handling overflow: do what?? */ + L->top -= EXTRA_STACK; + lua_error(L, "BAD STACK OVERFLOW! DATA CORRUPTED!!"); + } + else { + L->stack_last += EXTRA_STACK; /* to be used by error message */ + if (lua_stackedfunction(L, REC_DEEP) == LUA_NOOBJECT) { + /* less than REC_DEEP funcs on stack: doesn't look like a rec. loop */ + lua_error(L, "Lua2C - C2Lua overflow"); + } else lua_error(L, "stack size overflow"); } @@ -68,54 +69,62 @@ void luaD_checkstack (lua_State *L, int n) { } +static void restore_stack_limit (lua_State *L) { + if (L->top-L->stack < DEFAULT_STACK_SIZE-1) + L->stack_last = L->stack+(DEFAULT_STACK_SIZE-1); +} + + /* -** Adjust stack. Set top to the given value, pushing NILs if needed. +** Adjust stack. Set top to base+extra, pushing NILs if needed. +** (we cannot add base+extra unless we are sure it fits in the stack; +** otherwise the result of such operation on pointers is undefined) */ -void luaD_adjusttop (lua_State *L, StkId newtop) { - int diff = newtop-(L->stack.top-L->stack.stack); +void luaD_adjusttop (lua_State *L, StkId base, int extra) { + int diff = extra-(L->top-base); if (diff <= 0) - L->stack.top += diff; + L->top = base+extra; else { luaD_checkstack(L, diff); while (diff--) - ttype(L->stack.top++) = LUA_T_NIL; + ttype(L->top++) = LUA_T_NIL; } } /* -** Open a hole below "nelems" from the L->stack.top. +** Open a hole inside the stack at `pos' */ -void luaD_openstack (lua_State *L, int nelems) { - luaO_memup(L->stack.top-nelems+1, L->stack.top-nelems, - nelems*sizeof(TObject)); +void luaD_openstack (lua_State *L, StkId pos) { + luaO_memup(pos+1, pos, (L->top-pos)*sizeof(TObject)); incr_top; } void luaD_lineHook (lua_State *L, int line) { struct C_Lua_Stack oldCLS = L->Cstack; - StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack; + StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->top; L->Cstack.num = 0; (*L->linehook)(L, line); - L->stack.top = L->stack.stack+old_top; + L->top = old_top; L->Cstack = oldCLS; } -void luaD_callHook (lua_State *L, StkId base, const TProtoFunc *tf, int isreturn) { +void luaD_callHook (lua_State *L, StkId base, const TProtoFunc *tf, + int isreturn) { struct C_Lua_Stack oldCLS = L->Cstack; - StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->stack.top-L->stack.stack; + StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->top; L->Cstack.num = 0; if (isreturn) (*L->callhook)(L, LUA_NOOBJECT, "(return)", 0); else { - TObject *f = L->stack.stack+base-1; + TObject *f = base-1; if (tf) (*L->callhook)(L, Ref(L, f), tf->source->str, tf->lineDefined); else (*L->callhook)(L, Ref(L, f), "(C)", -1); } - L->stack.top = L->stack.stack+old_top; + L->top = old_top; L->Cstack = oldCLS; } @@ -126,43 +135,41 @@ void luaD_callHook (lua_State *L, StkId base, const TProtoFunc *tf, int isreturn ** first argument. Returns an index to the first result from C. */ static StkId callC (lua_State *L, lua_CFunction f, StkId base) { - struct C_Lua_Stack *cls = &L->Cstack; - struct C_Lua_Stack oldCLS = *cls; + struct C_Lua_Stack oldCLS = L->Cstack; StkId firstResult; - int numarg = (L->stack.top-L->stack.stack) - base; - cls->num = numarg; - cls->lua2C = base; - cls->base = base+numarg; /* == top-stack */ + int numarg = L->top - base; + L->Cstack.num = numarg; + L->Cstack.lua2C = base; + L->Cstack.base = L->top; if (L->callhook) luaD_callHook(L, base, NULL, 0); (*f)(L); /* do the actual call */ - if (L->callhook) /* func may have changed callhook */ + if (L->callhook) /* test again: `func' may have changed callhook */ luaD_callHook(L, base, NULL, 1); - firstResult = cls->base; - *cls = oldCLS; + firstResult = L->Cstack.base; + L->Cstack = oldCLS; return firstResult; } static StkId callCclosure (lua_State *L, const struct Closure *cl, lua_CFunction f, StkId base) { - TObject *pbase; int nup = cl->nelems; /* number of upvalues */ luaD_checkstack(L, nup); - pbase = L->stack.stack+base; /* care: previous call may change this */ /* open space for upvalues as extra arguments */ - luaO_memup(pbase+nup, pbase, (L->stack.top-pbase)*sizeof(TObject)); + luaO_memup(base+nup, base, (L->top-base)*sizeof(TObject)); /* copy upvalues into stack */ - memcpy(pbase, cl->consts+1, nup*sizeof(TObject)); - L->stack.top += nup; + memcpy(base, cl->consts+1, nup*sizeof(TObject)); + L->top += nup; return callC(L, f, base); } void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults) { - luaD_openstack(L, nParams); - *(L->stack.top-nParams-1) = *f; - luaD_call(L, L->stack.top-nParams-1, nResults); + StkId base = L->top - nParams; + luaD_openstack(L, base); + *base = *f; + luaD_call(L, base, nResults); } @@ -173,26 +180,24 @@ void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults) { ** function position. ** The number of results is nResults, unless nResults=MULT_RET. */ -void luaD_call (lua_State *L, TObject *func, int nResults) { - struct Stack *S = &L->stack; /* to optimize */ - StkId base = func - S->stack + 1; /* where is first argument */ +void luaD_call (lua_State *L, StkId func, int nResults) { StkId firstResult; switch (ttype(func)) { case LUA_T_CPROTO: ttype(func) = LUA_T_CMARK; - firstResult = callC(L, fvalue(func), base); + firstResult = callC(L, fvalue(func), func+1); break; case LUA_T_PROTO: ttype(func) = LUA_T_PMARK; - firstResult = luaV_execute(L, NULL, tfvalue(func), base); + firstResult = luaV_execute(L, NULL, tfvalue(func), func+1); break; case LUA_T_CLOSURE: { Closure *c = clvalue(func); TObject *proto = c->consts; ttype(func) = LUA_T_CLMARK; firstResult = (ttype(proto) == LUA_T_CPROTO) ? - callCclosure(L, c, fvalue(proto), base) : - luaV_execute(L, c, tfvalue(proto), base); + callCclosure(L, c, fvalue(proto), func+1) : + luaV_execute(L, c, tfvalue(proto), func+1); break; } default: { /* func is not a function */ @@ -200,19 +205,18 @@ void luaD_call (lua_State *L, TObject *func, int nResults) { const TObject *im = luaT_getimbyObj(L, func, IM_FUNCTION); if (ttype(im) == LUA_T_NIL) lua_error(L, "call expression not a function"); - luaD_callTM(L, im, (S->top-S->stack)-(base-1), nResults); + luaD_callTM(L, im, L->top-func, nResults); return; } } /* adjust the number of results */ if (nResults == MULT_RET) - nResults = (S->top-S->stack)-firstResult; + nResults = L->top - firstResult; else - luaD_adjusttop(L, firstResult+nResults); - /* move results to base-1 (to erase parameters and function) */ - base--; - luaO_memdown(S->stack+base, S->stack+firstResult, nResults*sizeof(TObject)); - S->top -= firstResult-base; + luaD_adjusttop(L, firstResult, nResults); + /* move results to func (to erase parameters and function) */ + luaO_memdown(func, firstResult, nResults*sizeof(TObject)); + L->top = func+nResults; } @@ -220,10 +224,10 @@ static void message (lua_State *L, const char *s) { const TObject *em = &(luaS_assertglobalbyname(L, "_ERRORMESSAGE")->value); if (ttype(em) == LUA_T_PROTO || ttype(em) == LUA_T_CPROTO || ttype(em) == LUA_T_CLOSURE) { - *L->stack.top = *em; + *L->top = *em; incr_top; lua_pushstring(L, s); - luaD_call(L, L->stack.top-2, 0); + luaD_call(L, L->top-2, 0); } } @@ -253,15 +257,16 @@ int luaD_protectedrun (lua_State *L) { L->errorJmp = &myErrorJmp; if (setjmp(myErrorJmp.b) == 0) { StkId base = L->Cstack.base; - luaD_call(L, L->stack.stack+base, MULT_RET); + luaD_call(L, base, MULT_RET); L->Cstack.lua2C = base; /* position of the new results */ - L->Cstack.num = (L->stack.top-L->stack.stack) - base; + L->Cstack.num = L->top - base; L->Cstack.base = base + L->Cstack.num; /* incorporate results on stack */ status = 0; } - else { /* an error occurred: restore L->Cstack and L->stack.top */ + else { /* an error occurred: restore the stack */ L->Cstack = oldCLS; - L->stack.top = L->stack.stack+L->Cstack.base; + L->top = L->Cstack.base; + restore_stack_limit(L); status = 1; } L->errorJmp = oldErr; @@ -283,18 +288,18 @@ static int protectedparser (lua_State *L, ZIO *z, int bin) { tf = bin ? luaU_undump1(L, z) : luaY_parser(L, z); status = 0; } - else { /* an error occurred: restore L->Cstack and L->stack.top */ + else { /* an error occurred: restore L->Cstack and L->top */ L->Cstack = oldCLS; - L->stack.top = L->stack.stack+L->Cstack.base; + L->top = L->Cstack.base; tf = NULL; status = 1; } L->errorJmp = oldErr; if (status) return 1; /* error code */ - if (tf == NULL) return 2; /* 'natural' end */ - luaD_adjusttop(L, L->Cstack.base+1); /* one slot for the pseudo-function */ - L->stack.stack[L->Cstack.base].ttype = LUA_T_PROTO; - L->stack.stack[L->Cstack.base].value.tf = tf; + if (tf == NULL) return 2; /* `natural' end */ + luaD_adjusttop(L, L->Cstack.base, 1); /* one slot for the pseudo-function */ + L->Cstack.base->ttype = LUA_T_PROTO; + L->Cstack.base->value.tf = tf; luaV_closure(L, 0); return 0; } @@ -323,7 +328,7 @@ static int do_main (lua_State *L, ZIO *z, int bin) { void luaD_gcIM (lua_State *L, const TObject *o) { const TObject *im = luaT_getimbyObj(L, o, IM_GC); if (ttype(im) != LUA_T_NIL) { - *L->stack.top = *o; + *L->top = *o; incr_top; luaD_callTM(L, im, 1, 0); } diff --git a/ldo.h b/ldo.h index d08adbb5..163de9d5 100644 --- a/ldo.h +++ b/ldo.h @@ -1,5 +1,5 @@ /* -** $Id: ldo.h,v 1.10 1999/11/22 13:12:07 roberto Exp roberto $ +** $Id: ldo.h,v 1.11 1999/11/25 18:58:51 roberto Exp roberto $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -20,22 +20,22 @@ ** macro to increment stack top. ** There must be always an empty slot at the L->stack.top */ -#define incr_top { if (L->stack.top >= L->stack.last) luaD_checkstack(L, 1); \ - L->stack.top++; } +#define incr_top {if (L->top == L->stack_last) luaD_checkstack(L, 1); L->top++;} /* macros to convert from lua_Object to (TObject *) and back */ -#define Address(L, lo) ((lo)+L->stack.stack-1) -#define Ref(L, st) ((st)-L->stack.stack+1) +#define Address(L, lo) ((lo)+L->stack-1) +#define Ref(L, st) ((st)-L->stack+1) void luaD_init (lua_State *L); -void luaD_adjusttop (lua_State *L, StkId newtop); -void luaD_openstack (lua_State *L, int nelems); +void luaD_adjusttop (lua_State *L, StkId base, int extra); +void luaD_openstack (lua_State *L, StkId pos); void luaD_lineHook (lua_State *L, int line); -void luaD_callHook (lua_State *L, StkId base, const TProtoFunc *tf, int isreturn); -void luaD_call (lua_State *L, TObject *func, int nResults); +void luaD_callHook (lua_State *L, StkId base, const TProtoFunc *tf, + int isreturn); +void luaD_call (lua_State *L, StkId func, int nResults); void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults); int luaD_protectedrun (lua_State *L); void luaD_gcIM (lua_State *L, const TObject *o); diff --git a/lgc.c b/lgc.c index c3259421..14ef9539 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 1.33 1999/11/23 13:58:02 roberto Exp roberto $ +** $Id: lgc.c,v 1.34 1999/11/26 18:59:20 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -77,9 +77,9 @@ static void travglobal (lua_State *L) { static void travstack (lua_State *L) { - StkId i; - for (i = (L->stack.top-1)-L->stack.stack; i>=0; i--) - markobject(L, L->stack.stack+i); + int i; + for (i = (L->top-1)-L->stack; i>=0; i--) + markobject(L, L->stack+i); } diff --git a/lparser.c b/lparser.c index 4305cc1d..df73fa31 100644 --- a/lparser.c +++ b/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 1.43 1999/11/22 13:12:07 roberto Exp roberto $ +** $Id: lparser.c,v 1.44 1999/11/25 18:59:43 roberto Exp roberto $ ** LL(1) Parser and code generator for Lua ** See Copyright Notice in lua.h */ @@ -581,8 +581,8 @@ static void init_state (LexState *ls, FuncState *fs, TaggedString *source) { code_byte(ls, 0); /* to be filled with maxstacksize */ code_byte(ls, 0); /* to be filled with arg information */ /* push function (to avoid GC) */ - tfvalue(L->stack.top) = f; - ttype(L->stack.top) = LUA_T_PROTO; + tfvalue(L->top) = f; + ttype(L->top) = LUA_T_PROTO; incr_top; } @@ -599,7 +599,7 @@ static void close_func (LexState *ls) { luaM_reallocvector(ls->L, f->locvars, fs->nvars, LocVar); } ls->fs = fs->prev; - ls->L->stack.top--; /* pop function */ + ls->L->top--; /* pop function */ } diff --git a/lstate.c b/lstate.c index 26a7ae68..fe2b4830 100644 --- a/lstate.c +++ b/lstate.c @@ -1,5 +1,5 @@ /* -** $Id: lstate.c,v 1.17 1999/11/22 13:12:07 roberto Exp roberto $ +** $Id: lstate.c,v 1.18 1999/11/29 19:12:07 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -23,9 +23,6 @@ lua_State *lua_state = NULL; lua_State *lua_newstate (void) { lua_State *L = luaM_new(NULL, lua_State); - L->Cstack.base = 0; - L->Cstack.lua2C = 0; - L->Cstack.num = 0; L->errorJmp = NULL; L->Mbuffer = NULL; L->Mbuffbase = 0; @@ -63,7 +60,7 @@ void lua_close (lua_State *L) { LUA_ASSERT(L, L->rootglobal == NULL, "list should be empty"); LUA_ASSERT(L, L->roottable == NULL, "list should be empty"); luaS_freeall(L); - luaM_free(L, L->stack.stack); + luaM_free(L, L->stack); luaM_free(L, L->IMtable); luaM_free(L, L->refArray); luaM_free(L, L->Mbuffer); diff --git a/lstate.h b/lstate.h index 2ee31840..1b946312 100644 --- a/lstate.h +++ b/lstate.h @@ -1,5 +1,5 @@ /* -** $Id: lstate.h,v 1.22 1999/11/10 15:39:35 roberto Exp roberto $ +** $Id: lstate.h,v 1.23 1999/11/22 13:12:07 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -15,7 +15,7 @@ -typedef int StkId; /* index to stack elements */ +typedef TObject *StkId; /* index to stack elements */ /* @@ -27,17 +27,16 @@ struct lua_longjmp { }; -struct Stack { - TObject *top; - TObject *stack; - TObject *last; -}; - +/* +** stack layout for C point of view: +** [lua2C, lua2C+num) - `array' lua2C +** [lua2C+num, base) - space for extra lua_Objects +** [base, L->top) - `stack' C2Lua +*/ struct C_Lua_Stack { - StkId base; /* when Lua calls C or C calls Lua, points to */ - /* the first slot after the last parameter. */ - StkId lua2C; /* points to first element of "array" lua2C */ - int num; /* size of "array" lua2C */ + StkId base; + StkId lua2C; + int num; }; @@ -51,7 +50,9 @@ typedef struct stringtable { struct lua_State { /* thread-specific state */ - struct Stack stack; /* Lua stack */ + StkId top; /* first free slot in the stack */ + StkId stack; /* stack base */ + StkId stack_last; /* last free slot in the stack */ struct C_Lua_Stack Cstack; /* C2lua struct */ struct lua_longjmp *errorJmp; /* current error recover point */ char *Mbuffer; /* global buffer */ diff --git a/lvm.c b/lvm.c index 32aa59f1..15349c64 100644 --- a/lvm.c +++ b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 1.67 1999/11/25 18:59:43 roberto Exp roberto $ +** $Id: lvm.c,v 1.68 1999/11/29 18:27:49 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -83,13 +83,12 @@ void luaV_setn (lua_State *L, Hash *t, int val) { void luaV_closure (lua_State *L, int nelems) { if (nelems > 0) { - struct Stack *S = &L->stack; Closure *c = luaF_newclosure(L, nelems); - c->consts[0] = *(S->top-1); - memcpy(&c->consts[1], S->top-(nelems+1), nelems*sizeof(TObject)); - S->top -= nelems; - ttype(S->top-1) = LUA_T_CLOSURE; - (S->top-1)->value.cl = c; + c->consts[0] = *(L->top-1); + L->top -= nelems; + memcpy(&c->consts[1], L->top-1, nelems*sizeof(TObject)); + ttype(L->top-1) = LUA_T_CLOSURE; + (L->top-1)->value.cl = c; } } @@ -99,7 +98,7 @@ void luaV_closure (lua_State *L, int nelems) { ** Receives the table at top-2 and the index at top-1. */ void luaV_gettable (lua_State *L) { - TObject *table = L->stack.top-2; + TObject *table = L->top-2; const TObject *im; if (ttype(table) != LUA_T_ARRAY) { /* not a table, get gettable method */ im = luaT_getimbyObj(L, table, IM_GETTABLE); @@ -117,7 +116,7 @@ void luaV_gettable (lua_State *L) { luaD_callTM(L, im, 2, 1); /* calls it */ } else { - L->stack.top--; + L->top--; *table = *h; /* "push" result into table position */ } return; @@ -132,8 +131,7 @@ void luaV_gettable (lua_State *L) { /* ** Receives table at *t, index at *(t+1) and value at top. */ -void luaV_settable (lua_State *L, const TObject *t) { - struct Stack *S = &L->stack; +void luaV_settable (lua_State *L, StkId t) { const TObject *im; if (ttype(t) != LUA_T_ARRAY) { /* not a table, get "settable" method */ im = luaT_getimbyObj(L, t, IM_SETTABLE); @@ -143,29 +141,28 @@ void luaV_settable (lua_State *L, const TObject *t) { else { /* object is a table... */ im = luaT_getim(L, avalue(t)->htag, IM_SETTABLE); if (ttype(im) == LUA_T_NIL) { /* and does not have a "settable" method */ - luaH_set(L, avalue(t), t+1, S->top-1); - S->top--; /* pop value */ + luaH_set(L, avalue(t), t+1, L->top-1); + L->top--; /* pop value */ return; } /* else it has a "settable" method, go through to next command */ } /* object is not a table, or it has a "settable" method */ /* prepare arguments and call the tag method */ - *(S->top+1) = *(L->stack.top-1); - *(S->top) = *(t+1); - *(S->top-1) = *t; - S->top += 2; /* WARNING: caller must assure stack space */ + *(L->top+1) = *(L->top-1); + *(L->top) = *(t+1); + *(L->top-1) = *t; + L->top += 2; /* WARNING: caller must assure stack space */ luaD_callTM(L, im, 3, 0); } -void luaV_rawsettable (lua_State *L, const TObject *t) { +void luaV_rawsettable (lua_State *L, StkId t) { if (ttype(t) != LUA_T_ARRAY) lua_error(L, "indexed expression not a table"); else { - struct Stack *S = &L->stack; - luaH_set(L, avalue(t), t+1, S->top-1); - S->top -= 3; + luaH_set(L, avalue(t), t+1, L->top-1); + L->top -= 3; } } @@ -178,17 +175,16 @@ void luaV_getglobal (lua_State *L, GlobalVar *gv) { case LUA_T_USERDATA: case LUA_T_ARRAY: case LUA_T_NIL: { TObject *im = luaT_getimbyObj(L, value, IM_GETGLOBAL); if (ttype(im) != LUA_T_NIL) { /* is there a tag method? */ - struct Stack *S = &L->stack; - ttype(S->top) = LUA_T_STRING; - tsvalue(S->top) = gv->name; /* global name */ - S->top++; - *S->top++ = *value; + ttype(L->top) = LUA_T_STRING; + tsvalue(L->top) = gv->name; /* global name */ + L->top++; + *L->top++ = *value; luaD_callTM(L, im, 2, 1); return; } /* else no tag method: go through to default behavior */ } - default: *L->stack.top++ = *value; /* default behavior */ + default: *L->top++ = *value; /* default behavior */ } } @@ -197,26 +193,26 @@ void luaV_setglobal (lua_State *L, GlobalVar *gv) { const TObject *oldvalue = &gv->value; const TObject *im = luaT_getimbyObj(L, oldvalue, IM_SETGLOBAL); if (ttype(im) == LUA_T_NIL) /* is there a tag method? */ - gv->value = *(--L->stack.top); + gv->value = *(--L->top); else { /* WARNING: caller must assure stack space */ - struct Stack *S = &L->stack; TObject newvalue; - newvalue = *(S->top-1); - ttype(S->top-1) = LUA_T_STRING; - tsvalue(S->top-1) = gv->name; - *S->top++ = *oldvalue; - *S->top++ = newvalue; + newvalue = *(L->top-1); + ttype(L->top-1) = LUA_T_STRING; + tsvalue(L->top-1) = gv->name; + *L->top++ = *oldvalue; + *L->top++ = newvalue; luaD_callTM(L, im, 3, 0); } } -static void call_binTM (lua_State *L, IMS event, const char *msg) { +static void call_binTM (lua_State *L, StkId top, IMS event, const char *msg) { /* try first operand */ - const TObject *im = luaT_getimbyObj(L, L->stack.top-2, event); + const TObject *im = luaT_getimbyObj(L, top-2, event); + L->top = top; if (ttype(im) == LUA_T_NIL) { - im = luaT_getimbyObj(L, L->stack.top-1, event); /* try second operand */ + im = luaT_getimbyObj(L, top-1, event); /* try second operand */ if (ttype(im) == LUA_T_NIL) { im = luaT_getim(L, 0, event); /* try a 'global' i.m. */ if (ttype(im) == LUA_T_NIL) @@ -228,8 +224,8 @@ static void call_binTM (lua_State *L, IMS event, const char *msg) { } -static void call_arith (lua_State *L, IMS event) { - call_binTM(L, event, "unexpected type in arithmetic operation"); +static void call_arith (lua_State *L, StkId top, IMS event) { + call_binTM(L, top, event, "unexpected type in arithmetic operation"); } @@ -249,11 +245,10 @@ static int luaV_strcomp (const char *l, long ll, const char *r, long lr) { } } -void luaV_comparison (lua_State *L, lua_Type ttype_less, lua_Type ttype_equal, - lua_Type ttype_great, IMS op) { - struct Stack *S = &L->stack; - const TObject *l = S->top-2; - const TObject *r = S->top-1; +void luaV_comparison (lua_State *L, StkId top, lua_Type ttype_less, + lua_Type ttype_equal, lua_Type ttype_great, IMS op) { + const TObject *l = top-2; + const TObject *r = top-1; real result; if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER) result = nvalue(l)-nvalue(r); @@ -261,39 +256,41 @@ void luaV_comparison (lua_State *L, lua_Type ttype_less, lua_Type ttype_equal, result = luaV_strcomp(svalue(l), tsvalue(l)->u.s.len, svalue(r), tsvalue(r)->u.s.len); else { - call_binTM(L, op, "unexpected type in comparison"); + call_binTM(L, top, op, "unexpected type in comparison"); return; } - S->top--; - nvalue(S->top-1) = 1; - ttype(S->top-1) = (result < 0) ? ttype_less : + nvalue(top-2) = 1; + ttype(top-2) = (result < 0) ? ttype_less : (result == 0) ? ttype_equal : ttype_great; } -void luaV_pack (lua_State *L, StkId firstel, int nvararg, TObject *tab) { - TObject *firstelem = L->stack.stack+firstel; +void luaV_pack (lua_State *L, StkId firstelem, int nvararg, TObject *tab) { int i; Hash *htab; - if (nvararg < 0) nvararg = 0; - htab = avalue(tab) = luaH_new(L, nvararg+1); /* +1 for field 'n' */ + htab = avalue(tab) = luaH_new(L, nvararg+1); /* +1 for field `n' */ ttype(tab) = LUA_T_ARRAY; for (i=0; istack.top-L->stack.stack)-first_extra_arg, &arg); - luaD_adjusttop(L, first_extra_arg); - *L->stack.top++ = arg; + int nvararg = (L->top-base) - nfixargs; + if (nvararg < 0) { + luaV_pack(L, base, 0, &arg); + luaD_adjusttop(L, base, nfixargs); + } + else { + luaV_pack(L, base+nfixargs, nvararg, &arg); + L->top = base+nfixargs; + } + *L->top++ = arg; } - /* ** Execute the given opcode, until a RET. Parameters are between ** [stack+base,top). Returns n such that the the results are between @@ -301,25 +298,26 @@ static void adjust_varargs (lua_State *L, StkId first_extra_arg) { */ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, StkId base) { - struct Stack *S = &L->stack; /* to optimize */ + register StkId top; /* keep top local, for performance */ register const Byte *pc = tf->code; const TObject *consts = tf->consts; if (L->callhook) luaD_callHook(L, base, tf, 0); luaD_checkstack(L, (*pc++)+EXTRA_STACK); if (*pc < ZEROVARARG) - luaD_adjusttop(L, base+*(pc++)); + luaD_adjusttop(L, base, *(pc++)); else { /* varargs */ + adjust_varargs(L, base, (*pc++)-ZEROVARARG); luaC_checkGC(L); - adjust_varargs(L, base+(*pc++)-ZEROVARARG); } + top = L->top; for (;;) { register int aux = 0; switchentry: switch ((OpCode)*pc++) { case ENDCODE: - S->top = S->stack + base; + top = base; goto ret; case RETCODE: @@ -327,238 +325,240 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, goto ret; case CALL: aux = *pc++; - luaD_call(L, (S->stack+base) + *pc++, aux); + L->top = top; + luaD_call(L, base+(*pc++), aux); + top = L->top; break; case TAILCALL: aux = *pc++; - luaD_call(L, (S->stack+base) + *pc++, MULT_RET); + L->top = top; + luaD_call(L, base+(*pc++), MULT_RET); + top = L->top; base += aux; goto ret; case PUSHNIL: aux = *pc++; do { - ttype(S->top++) = LUA_T_NIL; + ttype(top++) = LUA_T_NIL; } while (aux--); break; case POP: aux = *pc++; - S->top -= aux; + top -= aux; break; case PUSHNUMBERW: aux += highbyte(L, *pc++); case PUSHNUMBER: aux += *pc++; - ttype(S->top) = LUA_T_NUMBER; - nvalue(S->top) = aux; - S->top++; + ttype(top) = LUA_T_NUMBER; + nvalue(top) = aux; + top++; break; case PUSHNUMBERNEGW: aux += highbyte(L, *pc++); case PUSHNUMBERNEG: aux += *pc++; - ttype(S->top) = LUA_T_NUMBER; - nvalue(S->top) = -aux; - S->top++; + ttype(top) = LUA_T_NUMBER; + nvalue(top) = -aux; + top++; break; case PUSHCONSTANTW: aux += highbyte(L, *pc++); case PUSHCONSTANT: aux += *pc++; - *S->top++ = consts[aux]; + *top++ = consts[aux]; break; case PUSHUPVALUE: aux = *pc++; - *S->top++ = cl->consts[aux+1]; + *top++ = cl->consts[aux+1]; break; case PUSHLOCAL: aux = *pc++; - *S->top++ = *((S->stack+base) + aux); + *top++ = *(base+aux); break; case GETGLOBALW: aux += highbyte(L, *pc++); case GETGLOBAL: aux += *pc++; + L->top = top; luaV_getglobal(L, tsvalue(&consts[aux])->u.s.gv); + top++; break; case GETTABLE: + L->top = top; luaV_gettable(L); + top--; break; case GETDOTTEDW: aux += highbyte(L, *pc++); case GETDOTTED: aux += *pc++; - *S->top++ = consts[aux]; + *top++ = consts[aux]; + L->top = top; luaV_gettable(L); + top--; break; case PUSHSELFW: aux += highbyte(L, *pc++); case PUSHSELF: aux += *pc++; { TObject receiver; - receiver = *(S->top-1); - *S->top++ = consts[aux]; + receiver = *(top-1); + *top++ = consts[aux]; + L->top = top; luaV_gettable(L); - *S->top++ = receiver; + *(top-1) = receiver; break; } case CREATEARRAYW: aux += highbyte(L, *pc++); case CREATEARRAY: aux += *pc++; + L->top = top; luaC_checkGC(L); - avalue(S->top) = luaH_new(L, aux); - ttype(S->top) = LUA_T_ARRAY; - S->top++; + avalue(top) = luaH_new(L, aux); + ttype(top) = LUA_T_ARRAY; + top++; break; case SETLOCAL: aux = *pc++; - *((S->stack+base) + aux) = *(--S->top); + *(base+aux) = *(--top); break; case SETGLOBALW: aux += highbyte(L, *pc++); case SETGLOBAL: aux += *pc++; + L->top = top; luaV_setglobal(L, tsvalue(&consts[aux])->u.s.gv); + top--; break; case SETTABLEPOP: - luaV_settable(L, S->top-3); - S->top -= 2; /* pop table and index */ + L->top = top; + luaV_settable(L, top-3); + top -= 3; /* pop table, index, and value */ break; case SETTABLE: - luaV_settable(L, S->top-3-(*pc++)); + L->top = top; + luaV_settable(L, top-3-(*pc++)); + top--; /* pop value */ break; case SETLISTW: aux += highbyte(L, *pc++); case SETLIST: aux += *pc++; { int n = *(pc++); - Hash *arr = avalue(S->top-n-1); + Hash *arr = avalue(top-n-1); aux *= LFIELDS_PER_FLUSH; for (; n; n--) - luaH_setint(L, arr, n+aux, --S->top); + luaH_setint(L, arr, n+aux, --top); break; } case SETMAP: aux = *pc++; { - Hash *arr = avalue(S->top-(2*aux)-3); + Hash *arr = avalue(top-(2*aux)-3); do { - luaH_set(L, arr, S->top-2, S->top-1); - S->top-=2; + luaH_set(L, arr, top-2, top-1); + top-=2; } while (aux--); break; } case NEQOP: aux = 1; case EQOP: { - int res = luaO_equalObj(S->top-2, S->top-1); + int res = luaO_equalObj(top-2, top-1); if (aux) res = !res; - S->top--; - ttype(S->top-1) = res ? LUA_T_NUMBER : LUA_T_NIL; - nvalue(S->top-1) = 1; + top--; + ttype(top-1) = res ? LUA_T_NUMBER : LUA_T_NIL; + nvalue(top-1) = 1; break; } case LTOP: - luaV_comparison(L, LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT); + luaV_comparison(L, top, LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT); + top--; break; case LEOP: - luaV_comparison(L, LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, IM_LE); + luaV_comparison(L, top, LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, IM_LE); + top--; break; case GTOP: - luaV_comparison(L, LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, IM_GT); + luaV_comparison(L, top, LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, IM_GT); + top--; break; case GEOP: - luaV_comparison(L, LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, IM_GE); + luaV_comparison(L, top, LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, IM_GE); + top--; break; - case ADDOP: { - TObject *l = S->top-2; - TObject *r = S->top-1; - if (tonumber(r) || tonumber(l)) - call_arith(L, IM_ADD); - else { - nvalue(l) += nvalue(r); - --S->top; - } + case ADDOP: + if (tonumber(top-1) || tonumber(top-2)) + call_arith(L, top, IM_ADD); + else + nvalue(top-2) += nvalue(top-1); + top--; break; - } - case SUBOP: { - TObject *l = S->top-2; - TObject *r = S->top-1; - if (tonumber(r) || tonumber(l)) - call_arith(L, IM_SUB); - else { - nvalue(l) -= nvalue(r); - --S->top; - } + case SUBOP: + if (tonumber(top-1) || tonumber(top-2)) + call_arith(L, top, IM_SUB); + else + nvalue(top-2) -= nvalue(top-1); + top--; break; - } - case MULTOP: { - TObject *l = S->top-2; - TObject *r = S->top-1; - if (tonumber(r) || tonumber(l)) - call_arith(L, IM_MUL); - else { - nvalue(l) *= nvalue(r); - --S->top; - } + case MULTOP: + if (tonumber(top-1) || tonumber(top-2)) + call_arith(L, top, IM_MUL); + else + nvalue(top-2) *= nvalue(top-1); + top--; break; - } - case DIVOP: { - TObject *l = S->top-2; - TObject *r = S->top-1; - if (tonumber(r) || tonumber(l)) - call_arith(L, IM_DIV); - else { - nvalue(l) /= nvalue(r); - --S->top; - } + case DIVOP: + if (tonumber(top-1) || tonumber(top-2)) + call_arith(L, top, IM_DIV); + else + nvalue(top-2) /= nvalue(top-1); + top--; break; - } case POWOP: - call_binTM(L, IM_POW, "undefined operation"); + call_binTM(L, top, IM_POW, "undefined operation"); + top--; break; - case CONCOP: { - TObject *l = S->top-2; - TObject *r = S->top-1; - if (tostring(L, l) || tostring(L, r)) - call_binTM(L, IM_CONCAT, "unexpected type for concatenation"); - else { - tsvalue(l) = strconc(L, tsvalue(l), tsvalue(r)); - --S->top; - } + case CONCOP: + if (tostring(L, top-2) || tostring(L, top-1)) + call_binTM(L, top, IM_CONCAT, "unexpected type for concatenation"); + else + tsvalue(top-2) = strconc(L, tsvalue(top-2), tsvalue(top-1)); + L->top = top; luaC_checkGC(L); + top--; break; - } case MINUSOP: - if (tonumber(S->top-1)) { - ttype(S->top) = LUA_T_NIL; - S->top++; - call_arith(L, IM_UNM); + if (tonumber(top-1)) { + ttype(top) = LUA_T_NIL; + call_arith(L, top+1, IM_UNM); } else - nvalue(S->top-1) = - nvalue(S->top-1); + nvalue(top-1) = - nvalue(top-1); break; case NOTOP: - ttype(S->top-1) = - (ttype(S->top-1) == LUA_T_NIL) ? LUA_T_NUMBER : LUA_T_NIL; - nvalue(S->top-1) = 1; + ttype(top-1) = + (ttype(top-1) == LUA_T_NIL) ? LUA_T_NUMBER : LUA_T_NIL; + nvalue(top-1) = 1; break; case ONTJMPW: aux += highbyte(L, *pc++); case ONTJMP: aux += *pc++; - if (ttype(S->top-1) != LUA_T_NIL) pc += aux; - else S->top--; + if (ttype(top-1) != LUA_T_NIL) pc += aux; + else top--; break; case ONFJMPW: aux += highbyte(L, *pc++); case ONFJMP: aux += *pc++; - if (ttype(S->top-1) == LUA_T_NIL) pc += aux; - else S->top--; + if (ttype(top-1) == LUA_T_NIL) pc += aux; + else top--; break; case JMPW: aux += highbyte(L, *pc++); @@ -568,35 +568,40 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, case IFFJMPW: aux += highbyte(L, *pc++); case IFFJMP: aux += *pc++; - if (ttype(--S->top) == LUA_T_NIL) pc += aux; + if (ttype(--top) == LUA_T_NIL) pc += aux; break; case IFTUPJMPW: aux += highbyte(L, *pc++); case IFTUPJMP: aux += *pc++; - if (ttype(--S->top) != LUA_T_NIL) pc -= aux; + if (ttype(--top) != LUA_T_NIL) pc -= aux; break; case IFFUPJMPW: aux += highbyte(L, *pc++); case IFFUPJMP: aux += *pc++; - if (ttype(--S->top) == LUA_T_NIL) pc -= aux; + if (ttype(--top) == LUA_T_NIL) pc -= aux; break; case CLOSUREW: aux += highbyte(L, *pc++); case CLOSURE: aux += *pc++; - *S->top++ = consts[aux]; - luaV_closure(L, *pc++); + *top++ = consts[aux]; + L->top = top; + aux = *pc++; + luaV_closure(L, aux); luaC_checkGC(L); + top -= aux; break; case SETLINEW: aux += highbyte(L, *pc++); case SETLINE: aux += *pc++; - if ((S->stack+base-1)->ttype != LUA_T_LINE) { + L->top = top; + if ((base-1)->ttype != LUA_T_LINE) { /* open space for LINE value */ - luaD_openstack(L, (S->top-S->stack)-base); + luaD_openstack(L, base); + base->ttype = LUA_T_LINE; base++; - (S->stack+base-1)->ttype = LUA_T_LINE; + top++; } - (S->stack+base-1)->value.i = aux; + (base-1)->value.i = aux; if (L->linehook) luaD_lineHook(L, aux); break; @@ -608,8 +613,8 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, } } ret: + L->top = top; if (L->callhook) luaD_callHook(L, 0, NULL, 1); return base; } - diff --git a/lvm.h b/lvm.h index 8ddfd361..0768e570 100644 --- a/lvm.h +++ b/lvm.h @@ -1,5 +1,5 @@ /* -** $Id: lvm.h,v 1.11 1999/11/04 17:22:26 roberto Exp roberto $ +** $Id: lvm.h,v 1.12 1999/11/22 13:12:07 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -22,13 +22,13 @@ int luaV_tonumber (TObject *obj); int luaV_tostring (lua_State *L, TObject *obj); void luaV_setn (lua_State *L, Hash *t, int val); void luaV_gettable (lua_State *L); -void luaV_settable (lua_State *L, const TObject *t); -void luaV_rawsettable (lua_State *L, const TObject *t); +void luaV_settable (lua_State *L, StkId t); +void luaV_rawsettable (lua_State *L, StkId t); void luaV_getglobal (lua_State *L, GlobalVar *gv); void luaV_setglobal (lua_State *L, GlobalVar *gv); StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, StkId base); void luaV_closure (lua_State *L, int nelems); -void luaV_comparison (lua_State *L, lua_Type ttype_less, lua_Type ttype_equal, - lua_Type ttype_great, IMS op); +void luaV_comparison (lua_State *L, StkId top, lua_Type ttype_less, + lua_Type ttype_equal, lua_Type ttype_great, IMS op); #endif -- cgit v1.2.3-55-g6feb