mirror of https://github.com/rusefi/lua.git
fixed stack; first version.
This commit is contained in:
parent
3181dfefee
commit
fe237ad808
103
lapi.c
103
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
|
** Lua API
|
||||||
** See Copyright Notice in lua.h
|
** 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) {
|
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");
|
lua_error(L, "API error - wrong number of arguments in C2lua stack");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static lua_Object put_luaObject (lua_State *L, const TObject *o) {
|
static lua_Object put_luaObject (lua_State *L, const TObject *o) {
|
||||||
luaD_openstack(L, (L->stack.top-L->stack.stack)-L->Cstack.base);
|
luaD_openstack(L, L->Cstack.base);
|
||||||
L->stack.stack[L->Cstack.base++] = *o;
|
*L->Cstack.base++ = *o;
|
||||||
return L->Cstack.base; /* this is +1 real position (see Ref) */
|
return Ref(L, L->Cstack.base-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
lua_Object luaA_putObjectOnTop (lua_State *L) {
|
lua_Object luaA_putObjectOnTop (lua_State *L) {
|
||||||
luaD_openstack(L, (L->stack.top-L->stack.stack)-L->Cstack.base);
|
luaD_openstack(L, L->Cstack.base);
|
||||||
L->stack.stack[L->Cstack.base++] = *(--L->stack.top);
|
*L->Cstack.base++ = *(--L->top);
|
||||||
return L->Cstack.base; /* this is +1 real position (see Ref) */
|
return Ref(L, L->Cstack.base-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void top2LC (lua_State *L, int n) {
|
static void top2LC (lua_State *L, int n) {
|
||||||
/* Put the 'n' elements on the top as the Lua2C contents */
|
/* 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.lua2C = L->Cstack.base-n; /* position of the new results */
|
||||||
L->Cstack.num = n; /* number of 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.
|
** 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) {
|
lua_Object lua_lua2C (lua_State *L, int number) {
|
||||||
if (number <= 0 || number > L->Cstack.num) return LUA_NOOBJECT;
|
if (number <= 0 || number > L->Cstack.num) return LUA_NOOBJECT;
|
||||||
/* Ref(L, L->stack.stack+(L->Cstack.lua2C+number-1)) ==
|
return Ref(L, L->Cstack.lua2C+number-1);
|
||||||
L->stack.stack+(L->Cstack.lua2C+number-1)-L->stack.stack+1 == */
|
|
||||||
return L->Cstack.lua2C+number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -112,8 +110,8 @@ int lua_callfunction (lua_State *L, lua_Object function) {
|
||||||
if (function == LUA_NOOBJECT)
|
if (function == LUA_NOOBJECT)
|
||||||
return 1;
|
return 1;
|
||||||
else {
|
else {
|
||||||
luaD_openstack(L, (L->stack.top-L->stack.stack)-L->Cstack.base);
|
luaD_openstack(L, L->Cstack.base);
|
||||||
set_normalized(L->stack.stack+L->Cstack.base, Address(L, function));
|
set_normalized(L->Cstack.base, Address(L, function));
|
||||||
return luaD_protectedrun(L);
|
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) {
|
lua_Object lua_settagmethod (lua_State *L, int tag, const char *event) {
|
||||||
checkCparams(L, 1);
|
checkCparams(L, 1);
|
||||||
luaT_settagmethod(L, tag, event, L->stack.top-1);
|
luaT_settagmethod(L, tag, event, L->top-1);
|
||||||
return luaA_putObjectOnTop(L);
|
return luaA_putObjectOnTop(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,24 +147,24 @@ lua_Object lua_gettable (lua_State *L) {
|
||||||
|
|
||||||
lua_Object lua_rawgettable (lua_State *L) {
|
lua_Object lua_rawgettable (lua_State *L) {
|
||||||
checkCparams(L, 2);
|
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");
|
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->top-2) = *luaH_get(L, avalue(L->top-2), L->top-1);
|
||||||
--L->stack.top;
|
--L->top;
|
||||||
return luaA_putObjectOnTop(L);
|
return luaA_putObjectOnTop(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void lua_settable (lua_State *L) {
|
void lua_settable (lua_State *L) {
|
||||||
checkCparams(L, 3);
|
checkCparams(L, 3);
|
||||||
luaV_settable(L, L->stack.top-3);
|
luaV_settable(L, L->top-3);
|
||||||
L->stack.top -= 2; /* pop table and index */
|
L->top -= 2; /* pop table and index */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void lua_rawsettable (lua_State *L) {
|
void lua_rawsettable (lua_State *L) {
|
||||||
checkCparams(L, 3);
|
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) {
|
void lua_rawsetglobal (lua_State *L, const char *name) {
|
||||||
GlobalVar *gv = luaS_assertglobalbyname(L, name);
|
GlobalVar *gv = luaS_assertglobalbyname(L, name);
|
||||||
checkCparams(L, 1);
|
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) {
|
void lua_pushnil (lua_State *L) {
|
||||||
ttype(L->stack.top) = LUA_T_NIL;
|
ttype(L->top) = LUA_T_NIL;
|
||||||
incr_top;
|
incr_top;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lua_pushnumber (lua_State *L, double n) {
|
void lua_pushnumber (lua_State *L, double n) {
|
||||||
ttype(L->stack.top) = LUA_T_NUMBER;
|
ttype(L->top) = LUA_T_NUMBER;
|
||||||
nvalue(L->stack.top) = n;
|
nvalue(L->top) = n;
|
||||||
incr_top;
|
incr_top;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lua_pushlstring (lua_State *L, const char *s, long len) {
|
void lua_pushlstring (lua_State *L, const char *s, long len) {
|
||||||
tsvalue(L->stack.top) = luaS_newlstr(L, s, len);
|
tsvalue(L->top) = luaS_newlstr(L, s, len);
|
||||||
ttype(L->stack.top) = LUA_T_STRING;
|
ttype(L->top) = LUA_T_STRING;
|
||||||
incr_top;
|
incr_top;
|
||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
}
|
}
|
||||||
|
@ -308,8 +306,8 @@ void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
|
||||||
if (fn == NULL)
|
if (fn == NULL)
|
||||||
lua_error(L, "API error - attempt to push a NULL Cfunction");
|
lua_error(L, "API error - attempt to push a NULL Cfunction");
|
||||||
checkCparams(L, n);
|
checkCparams(L, n);
|
||||||
ttype(L->stack.top) = LUA_T_CPROTO;
|
ttype(L->top) = LUA_T_CPROTO;
|
||||||
fvalue(L->stack.top) = fn;
|
fvalue(L->top) = fn;
|
||||||
incr_top;
|
incr_top;
|
||||||
luaV_closure(L, n);
|
luaV_closure(L, n);
|
||||||
luaC_checkGC(L);
|
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) {
|
void lua_pushusertag (lua_State *L, void *u, int tag) {
|
||||||
if (tag < 0 && tag != LUA_ANYTAG)
|
if (tag < 0 && tag != LUA_ANYTAG)
|
||||||
luaT_realtag(L, tag); /* error if tag is not valid */
|
luaT_realtag(L, tag); /* error if tag is not valid */
|
||||||
tsvalue(L->stack.top) = luaS_createudata(L, u, tag);
|
tsvalue(L->top) = luaS_createudata(L, u, tag);
|
||||||
ttype(L->stack.top) = LUA_T_USERDATA;
|
ttype(L->top) = LUA_T_USERDATA;
|
||||||
incr_top;
|
incr_top;
|
||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
void luaA_pushobject (lua_State *L, const TObject *o) {
|
void luaA_pushobject (lua_State *L, const TObject *o) {
|
||||||
*L->stack.top = *o;
|
*L->top = *o;
|
||||||
incr_top;
|
incr_top;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lua_pushobject (lua_State *L, lua_Object o) {
|
void lua_pushobject (lua_State *L, lua_Object o) {
|
||||||
if (o == LUA_NOOBJECT)
|
if (o == LUA_NOOBJECT)
|
||||||
lua_error(L, "API error - attempt to push a 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;
|
incr_top;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,18 +366,18 @@ int lua_tag (lua_State *L, lua_Object lo) {
|
||||||
void lua_settag (lua_State *L, int tag) {
|
void lua_settag (lua_State *L, int tag) {
|
||||||
checkCparams(L, 1);
|
checkCparams(L, 1);
|
||||||
luaT_realtag(L, tag);
|
luaT_realtag(L, tag);
|
||||||
switch (ttype(L->stack.top-1)) {
|
switch (ttype(L->top-1)) {
|
||||||
case LUA_T_ARRAY:
|
case LUA_T_ARRAY:
|
||||||
(L->stack.top-1)->value.a->htag = tag;
|
(L->top-1)->value.a->htag = tag;
|
||||||
break;
|
break;
|
||||||
case LUA_T_USERDATA:
|
case LUA_T_USERDATA:
|
||||||
(L->stack.top-1)->value.ts->u.d.tag = tag;
|
(L->top-1)->value.ts->u.d.tag = tag;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
luaL_verror(L, "cannot change the tag of a %.20s",
|
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 */
|
while (gv && gv->value.ttype == LUA_T_NIL) /* skip globals with nil */
|
||||||
gv = gv->next;
|
gv = gv->next;
|
||||||
if (gv) {
|
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;
|
incr_top;
|
||||||
luaA_pushobject(L, &gv->value);
|
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) {
|
lua_Function lua_stackedfunction (lua_State *L, int level) {
|
||||||
StkId i;
|
int i;
|
||||||
for (i = (L->stack.top-1)-L->stack.stack; i>=0; i--) {
|
for (i = (L->top-1)-L->stack; i>=0; i--) {
|
||||||
int t = L->stack.stack[i].ttype;
|
int t = L->stack[i].ttype;
|
||||||
if (t == LUA_T_CLMARK || t == LUA_T_PMARK || t == LUA_T_CMARK)
|
if (t == LUA_T_CLMARK || t == LUA_T_PMARK || t == LUA_T_CMARK)
|
||||||
if (level-- == 0)
|
if (level-- == 0)
|
||||||
return Ref(L, L->stack.stack+i);
|
return Ref(L, L->stack+i);
|
||||||
}
|
}
|
||||||
return LUA_NOOBJECT;
|
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) {
|
int lua_currentline (lua_State *L, lua_Function func) {
|
||||||
const TObject *f = Address(L, func);
|
const TObject *f = Address(L, func);
|
||||||
return (f+1 < L->stack.top && (f+1)->ttype == LUA_T_LINE) ?
|
return (f+1 < L->top && (f+1)->ttype == LUA_T_LINE) ? (f+1)->value.i : -1;
|
||||||
(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,
|
const char *name = luaF_getlocalname(fp, local_number,
|
||||||
lua_currentline(L, func));
|
lua_currentline(L, func));
|
||||||
checkCparams(L, 1);
|
checkCparams(L, 1);
|
||||||
--L->stack.top;
|
--L->top;
|
||||||
if (name) {
|
if (name) {
|
||||||
/* if "name", there must be a LUA_T_LINE */
|
/* if "name", there must be a LUA_T_LINE */
|
||||||
/* therefore, f+2 points to function base */
|
/* therefore, f+2 points to function base */
|
||||||
*((f+2)+(local_number-1)) = *L->stack.top;
|
*((f+2)+(local_number-1)) = *L->top;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -565,14 +562,14 @@ void lua_funcinfo (lua_State *L, lua_Object func,
|
||||||
|
|
||||||
|
|
||||||
static int checkfunc (lua_State *L, TObject *o) {
|
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) {
|
const char *lua_getobjname (lua_State *L, lua_Object o, const char **name) {
|
||||||
/* try to find a name for given function */
|
/* try to find a name for given function */
|
||||||
GlobalVar *g;
|
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) {
|
for (g=L->rootglobal; g; g=g->next) {
|
||||||
if (checkfunc(L, &g->value)) {
|
if (checkfunc(L, &g->value)) {
|
||||||
*name = g->name->str;
|
*name = g->name->str;
|
||||||
|
@ -610,7 +607,7 @@ void lua_beginblock (lua_State *L) {
|
||||||
void lua_endblock (lua_State *L) {
|
void lua_endblock (lua_State *L) {
|
||||||
--L->numCblocks;
|
--L->numCblocks;
|
||||||
L->Cstack = L->Cblocks[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 lua_ref (lua_State *L, int lock) {
|
||||||
int ref;
|
int ref;
|
||||||
checkCparams(L, 1);
|
checkCparams(L, 1);
|
||||||
ref = luaR_ref(L, L->stack.top-1, lock);
|
ref = luaR_ref(L, L->top-1, lock);
|
||||||
L->stack.top--;
|
L->top--;
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
99
lbuiltin.c
99
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
|
** Built-in functions
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -37,8 +37,8 @@
|
||||||
|
|
||||||
|
|
||||||
static void pushtagstring (lua_State *L, TaggedString *s) {
|
static void pushtagstring (lua_State *L, TaggedString *s) {
|
||||||
ttype(L->stack.top) = LUA_T_STRING;
|
ttype(L->top) = LUA_T_STRING;
|
||||||
tsvalue(L->stack.top) = s;
|
tsvalue(L->top) = s;
|
||||||
incr_top;
|
incr_top;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,7 +303,7 @@ static void luaB_call (lua_State *L) {
|
||||||
/* push arg[1...n] */
|
/* push arg[1...n] */
|
||||||
luaD_checkstack(L, narg);
|
luaD_checkstack(L, narg);
|
||||||
for (i=0; i<narg; i++)
|
for (i=0; i<narg; i++)
|
||||||
*(L->stack.top++) = *luaH_getint(L, arg, i+1);
|
*(L->top++) = *luaH_getint(L, arg, i+1);
|
||||||
status = lua_callfunction(L, f);
|
status = lua_callfunction(L, f);
|
||||||
if (err != LUA_NOOBJECT) { /* restore old error method */
|
if (err != LUA_NOOBJECT) { /* restore old error method */
|
||||||
lua_pushobject(L, err);
|
lua_pushobject(L, err);
|
||||||
|
@ -319,7 +319,7 @@ static void luaB_call (lua_State *L) {
|
||||||
}
|
}
|
||||||
else { /* no errors */
|
else { /* no errors */
|
||||||
if (strchr(options, 'p')) { /* pack results? */
|
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;
|
incr_top;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -414,65 +414,60 @@ static void luaB_assert (lua_State *L) {
|
||||||
|
|
||||||
|
|
||||||
static void luaB_foreachi (lua_State *L) {
|
static void luaB_foreachi (lua_State *L) {
|
||||||
struct Stack *S = &L->stack;
|
|
||||||
const Hash *t = gettable(L, 1);
|
const Hash *t = gettable(L, 1);
|
||||||
int n = (int)getnarg(L, t);
|
int n = (int)getnarg(L, t);
|
||||||
int i;
|
int i;
|
||||||
StkId f = luaA_Address(L, luaL_functionarg(L, 2)) - S->stack;
|
StkId f = luaA_Address(L, luaL_functionarg(L, 2));
|
||||||
/* 'f' cannot be a pointer to TObject, because it is on the stack, and the
|
|
||||||
stack may be reallocated by the call. */
|
|
||||||
luaD_checkstack(L, 3); /* for f, key, and val */
|
luaD_checkstack(L, 3); /* for f, key, and val */
|
||||||
for (i=1; i<=n; i++) {
|
for (i=1; i<=n; i++) {
|
||||||
*(S->top++) = *(S->stack+f);
|
*(L->top++) = *f;
|
||||||
ttype(S->top) = LUA_T_NUMBER; nvalue(S->top++) = i;
|
ttype(L->top) = LUA_T_NUMBER; nvalue(L->top++) = i;
|
||||||
*(S->top++) = *luaH_getint(L, t, i);
|
*(L->top++) = *luaH_getint(L, t, i);
|
||||||
luaD_call(L, S->top-3, 1);
|
luaD_call(L, L->top-3, 1);
|
||||||
if (ttype(S->top-1) != LUA_T_NIL)
|
if (ttype(L->top-1) != LUA_T_NIL)
|
||||||
return;
|
return;
|
||||||
S->top--;
|
L->top--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void luaB_foreach (lua_State *L) {
|
static void luaB_foreach (lua_State *L) {
|
||||||
struct Stack *S = &L->stack;
|
|
||||||
const Hash *a = gettable(L, 1);
|
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;
|
int i;
|
||||||
luaD_checkstack(L, 3); /* for f, key, and val */
|
luaD_checkstack(L, 3); /* for f, key, and val */
|
||||||
for (i=0; i<a->size; i++) {
|
for (i=0; i<a->size; i++) {
|
||||||
const Node *nd = &(a->node[i]);
|
const Node *nd = &(a->node[i]);
|
||||||
if (ttype(val(nd)) != LUA_T_NIL) {
|
if (ttype(val(nd)) != LUA_T_NIL) {
|
||||||
*(S->top++) = *(S->stack+f);
|
*(L->top++) = *f;
|
||||||
*(S->top++) = *key(nd);
|
*(L->top++) = *key(nd);
|
||||||
*(S->top++) = *val(nd);
|
*(L->top++) = *val(nd);
|
||||||
luaD_call(L, S->top-3, 1);
|
luaD_call(L, L->top-3, 1);
|
||||||
if (ttype(S->top-1) != LUA_T_NIL)
|
if (ttype(L->top-1) != LUA_T_NIL)
|
||||||
return;
|
return;
|
||||||
S->top--; /* remove result */
|
L->top--; /* remove result */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void luaB_foreachvar (lua_State *L) {
|
static void luaB_foreachvar (lua_State *L) {
|
||||||
struct Stack *S = &L->stack;
|
StkId f = luaA_Address(L, luaL_functionarg(L, 1));
|
||||||
StkId f = luaA_Address(L, luaL_functionarg(L, 1)) - S->stack;
|
|
||||||
GlobalVar *gv;
|
GlobalVar *gv;
|
||||||
luaD_checkstack(L, 4); /* for extra var name, f, var name, and globalval */
|
luaD_checkstack(L, 4); /* for extra var name, f, var name, and globalval */
|
||||||
for (gv = L->rootglobal; gv; gv = gv->next) {
|
for (gv = L->rootglobal; gv; gv = gv->next) {
|
||||||
if (gv->value.ttype != LUA_T_NIL) {
|
if (gv->value.ttype != LUA_T_NIL) {
|
||||||
pushtagstring(L, gv->name); /* keep (extra) name on stack to avoid GC */
|
pushtagstring(L, gv->name); /* keep (extra) name on stack to avoid GC */
|
||||||
*(S->top++) = *(S->stack+f);
|
*(L->top++) = *f;
|
||||||
pushtagstring(L, gv->name);
|
pushtagstring(L, gv->name);
|
||||||
*(S->top++) = gv->value;
|
*(L->top++) = gv->value;
|
||||||
luaD_call(L, S->top-3, 1);
|
luaD_call(L, L->top-3, 1);
|
||||||
if (ttype(S->top-1) != LUA_T_NIL) {
|
if (ttype(L->top-1) != LUA_T_NIL) {
|
||||||
S->top--;
|
L->top--;
|
||||||
*(S->top-1) = *S->top; /* remove extra name */
|
*(L->top-1) = *L->top; /* remove extra name */
|
||||||
return;
|
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) {
|
const TObject *b) {
|
||||||
/* notice: the caller (auxsort) must check stack space */
|
/* notice: the caller (auxsort) must check stack space */
|
||||||
if (f != LUA_NOOBJECT) {
|
if (f != LUA_NOOBJECT) {
|
||||||
*(L->stack.top) = *luaA_Address(L, f);
|
*(L->top) = *luaA_Address(L, f);
|
||||||
*(L->stack.top+1) = *a;
|
*(L->top+1) = *a;
|
||||||
*(L->stack.top+2) = *b;
|
*(L->top+2) = *b;
|
||||||
L->stack.top += 3;
|
L->top += 3;
|
||||||
luaD_call(L, L->stack.top-3, 1);
|
luaD_call(L, L->top-3, 1);
|
||||||
}
|
}
|
||||||
else { /* a < b? */
|
else { /* a < b? */
|
||||||
*(L->stack.top) = *a;
|
*(L->top) = *a;
|
||||||
*(L->stack.top+1) = *b;
|
*(L->top+1) = *b;
|
||||||
L->stack.top += 2;
|
luaV_comparison(L, L->top+2, LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT);
|
||||||
luaV_comparison(L, 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) {
|
static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) {
|
||||||
struct Stack *S = &L->stack;
|
StkId P = L->top++; /* temporary place for pivot */
|
||||||
StkId P = S->top - S->stack; /* temporary place for pivot */
|
ttype(P) = LUA_T_NIL;
|
||||||
S->top++;
|
|
||||||
ttype(S->stack+P) = LUA_T_NIL;
|
|
||||||
while (l < u) { /* for tail recursion */
|
while (l < u) { /* for tail recursion */
|
||||||
int i, j;
|
int i, j;
|
||||||
/* sort elements a[l], a[(l+u)/2] and a[u] */
|
/* 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]<a[l] */
|
swap(L, a, l, u); /* a[u]<a[l] */
|
||||||
if (u-l == 1) break; /* only 2 elements */
|
if (u-l == 1) break; /* only 2 elements */
|
||||||
i = (l+u)/2;
|
i = (l+u)/2;
|
||||||
*(S->stack+P) = *luaH_getint(L, a, i); /* P = a[i] */
|
*P = *luaH_getint(L, a, i); /* P = a[i] */
|
||||||
if (sort_comp(L, f, S->stack+P, luaH_getint(L, a, l))) /* a[i]<a[l]? */
|
if (sort_comp(L, f, P, luaH_getint(L, a, l))) /* a[i]<a[l]? */
|
||||||
swap(L, a, l, i);
|
swap(L, a, l, i);
|
||||||
else if (sort_comp(L, f, luaH_getint(L, a, u), S->stack+P)) /* a[u]<a[i]? */
|
else if (sort_comp(L, f, luaH_getint(L, a, u), P)) /* a[u]<a[i]? */
|
||||||
swap(L, a, i, u);
|
swap(L, a, i, u);
|
||||||
if (u-l == 2) break; /* only 3 elements */
|
if (u-l == 2) break; /* only 3 elements */
|
||||||
*(S->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]) */
|
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 */
|
/* a[l] <= P == a[u-1] <= a[u], only needs to sort from l+1 to u-2 */
|
||||||
i = l; j = u-1;
|
i = l; j = u-1;
|
||||||
for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
|
for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
|
||||||
/* repeat i++ until a[i] >= P */
|
/* 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");
|
if (i>u) lua_error(L, "invalid order function for sorting");
|
||||||
/* repeat j-- until a[j] <= P */
|
/* 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 (j<l) lua_error(L, "invalid order function for sorting");
|
if (j<l) lua_error(L, "invalid order function for sorting");
|
||||||
if (j<i) break;
|
if (j<i) break;
|
||||||
swap(L, a, i, j);
|
swap(L, a, i, j);
|
||||||
|
@ -588,7 +581,7 @@ static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) {
|
||||||
}
|
}
|
||||||
auxsort(L, a, j, i, f); /* call recursively the smaller one */
|
auxsort(L, a, j, i, f); /* call recursively the smaller one */
|
||||||
} /* repeat the routine for the larger one */
|
} /* repeat the routine for the larger one */
|
||||||
S->top--; /* remove pivot from stack */
|
L->top--; /* remove pivot from stack */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void luaB_sort (lua_State *L) {
|
static void luaB_sort (lua_State *L) {
|
||||||
|
|
171
ldo.c
171
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
|
** Stack and Call structure of Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -28,39 +28,40 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef STACK_LIMIT
|
#ifndef DEFAULT_STACK_SIZE
|
||||||
#define STACK_LIMIT 6000 /* arbitrary limit */
|
#define DEFAULT_STACK_SIZE 1024
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define EXTRA_STACK 32 /* space to handle stack overflow errors */
|
||||||
|
|
||||||
|
/*
|
||||||
#define STACK_UNIT 128
|
** typical numer of recursive calls that fit in the stack
|
||||||
|
** (only for error messages)
|
||||||
|
*/
|
||||||
#ifdef DEBUG
|
#define REC_DEEP (DEFAULT_STACK_SIZE/20)
|
||||||
#undef STACK_UNIT
|
|
||||||
#define STACK_UNIT 2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
void luaD_init (lua_State *L) {
|
void luaD_init (lua_State *L) {
|
||||||
L->stack.stack = luaM_newvector(L, STACK_UNIT, TObject);
|
L->stack = luaM_newvector(L, DEFAULT_STACK_SIZE+EXTRA_STACK, TObject);
|
||||||
L->stack.top = L->stack.stack;
|
L->stack_last = L->stack+(DEFAULT_STACK_SIZE-1);
|
||||||
L->stack.last = L->stack.stack+(STACK_UNIT-1);
|
L->Cstack.base = L->Cstack.lua2C = L->top = L->stack;
|
||||||
|
L->Cstack.num = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaD_checkstack (lua_State *L, int n) {
|
void luaD_checkstack (lua_State *L, int n) {
|
||||||
struct Stack *S = &L->stack;
|
if (L->stack_last-L->top <= n) { /* stack overflow? */
|
||||||
if (S->last-S->top <= n) {
|
if (L->stack_last-L->stack > (DEFAULT_STACK_SIZE-1)) {
|
||||||
StkId top = S->top-S->stack;
|
/* overflow while handling overflow: do what?? */
|
||||||
int stacksize = (S->last-S->stack)+STACK_UNIT+n;
|
L->top -= EXTRA_STACK;
|
||||||
luaM_reallocvector(L, S->stack, stacksize, TObject);
|
lua_error(L, "BAD STACK OVERFLOW! DATA CORRUPTED!!");
|
||||||
S->last = S->stack+(stacksize-1);
|
}
|
||||||
S->top = S->stack + top;
|
else {
|
||||||
if (stacksize >= STACK_LIMIT) { /* stack overflow? */
|
L->stack_last += EXTRA_STACK; /* to be used by error message */
|
||||||
if (lua_stackedfunction(L, 100) == LUA_NOOBJECT) /* 100 funcs on stack? */
|
if (lua_stackedfunction(L, REC_DEEP) == LUA_NOOBJECT) {
|
||||||
lua_error(L, "Lua2C - C2Lua overflow"); /* doesn't look like a rec. loop */
|
/* less than REC_DEEP funcs on stack: doesn't look like a rec. loop */
|
||||||
|
lua_error(L, "Lua2C - C2Lua overflow");
|
||||||
|
}
|
||||||
else
|
else
|
||||||
lua_error(L, "stack size overflow");
|
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) {
|
void luaD_adjusttop (lua_State *L, StkId base, int extra) {
|
||||||
int diff = newtop-(L->stack.top-L->stack.stack);
|
int diff = extra-(L->top-base);
|
||||||
if (diff <= 0)
|
if (diff <= 0)
|
||||||
L->stack.top += diff;
|
L->top = base+extra;
|
||||||
else {
|
else {
|
||||||
luaD_checkstack(L, diff);
|
luaD_checkstack(L, diff);
|
||||||
while (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) {
|
void luaD_openstack (lua_State *L, StkId pos) {
|
||||||
luaO_memup(L->stack.top-nelems+1, L->stack.top-nelems,
|
luaO_memup(pos+1, pos, (L->top-pos)*sizeof(TObject));
|
||||||
nelems*sizeof(TObject));
|
|
||||||
incr_top;
|
incr_top;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaD_lineHook (lua_State *L, int line) {
|
void luaD_lineHook (lua_State *L, int line) {
|
||||||
struct C_Lua_Stack oldCLS = L->Cstack;
|
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->Cstack.num = 0;
|
||||||
(*L->linehook)(L, line);
|
(*L->linehook)(L, line);
|
||||||
L->stack.top = L->stack.stack+old_top;
|
L->top = old_top;
|
||||||
L->Cstack = oldCLS;
|
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;
|
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->Cstack.num = 0;
|
||||||
if (isreturn)
|
if (isreturn)
|
||||||
(*L->callhook)(L, LUA_NOOBJECT, "(return)", 0);
|
(*L->callhook)(L, LUA_NOOBJECT, "(return)", 0);
|
||||||
else {
|
else {
|
||||||
TObject *f = L->stack.stack+base-1;
|
TObject *f = base-1;
|
||||||
if (tf)
|
if (tf)
|
||||||
(*L->callhook)(L, Ref(L, f), tf->source->str, tf->lineDefined);
|
(*L->callhook)(L, Ref(L, f), tf->source->str, tf->lineDefined);
|
||||||
else (*L->callhook)(L, Ref(L, f), "(C)", -1);
|
else (*L->callhook)(L, Ref(L, f), "(C)", -1);
|
||||||
}
|
}
|
||||||
L->stack.top = L->stack.stack+old_top;
|
L->top = old_top;
|
||||||
L->Cstack = oldCLS;
|
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.
|
** first argument. Returns an index to the first result from C.
|
||||||
*/
|
*/
|
||||||
static StkId callC (lua_State *L, lua_CFunction f, StkId base) {
|
static StkId callC (lua_State *L, lua_CFunction f, StkId base) {
|
||||||
struct C_Lua_Stack *cls = &L->Cstack;
|
struct C_Lua_Stack oldCLS = L->Cstack;
|
||||||
struct C_Lua_Stack oldCLS = *cls;
|
|
||||||
StkId firstResult;
|
StkId firstResult;
|
||||||
int numarg = (L->stack.top-L->stack.stack) - base;
|
int numarg = L->top - base;
|
||||||
cls->num = numarg;
|
L->Cstack.num = numarg;
|
||||||
cls->lua2C = base;
|
L->Cstack.lua2C = base;
|
||||||
cls->base = base+numarg; /* == top-stack */
|
L->Cstack.base = L->top;
|
||||||
if (L->callhook)
|
if (L->callhook)
|
||||||
luaD_callHook(L, base, NULL, 0);
|
luaD_callHook(L, base, NULL, 0);
|
||||||
(*f)(L); /* do the actual call */
|
(*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);
|
luaD_callHook(L, base, NULL, 1);
|
||||||
firstResult = cls->base;
|
firstResult = L->Cstack.base;
|
||||||
*cls = oldCLS;
|
L->Cstack = oldCLS;
|
||||||
return firstResult;
|
return firstResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static StkId callCclosure (lua_State *L, const struct Closure *cl,
|
static StkId callCclosure (lua_State *L, const struct Closure *cl,
|
||||||
lua_CFunction f, StkId base) {
|
lua_CFunction f, StkId base) {
|
||||||
TObject *pbase;
|
|
||||||
int nup = cl->nelems; /* number of upvalues */
|
int nup = cl->nelems; /* number of upvalues */
|
||||||
luaD_checkstack(L, nup);
|
luaD_checkstack(L, nup);
|
||||||
pbase = L->stack.stack+base; /* care: previous call may change this */
|
|
||||||
/* open space for upvalues as extra arguments */
|
/* 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 */
|
/* copy upvalues into stack */
|
||||||
memcpy(pbase, cl->consts+1, nup*sizeof(TObject));
|
memcpy(base, cl->consts+1, nup*sizeof(TObject));
|
||||||
L->stack.top += nup;
|
L->top += nup;
|
||||||
return callC(L, f, base);
|
return callC(L, f, base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults) {
|
void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults) {
|
||||||
luaD_openstack(L, nParams);
|
StkId base = L->top - nParams;
|
||||||
*(L->stack.top-nParams-1) = *f;
|
luaD_openstack(L, base);
|
||||||
luaD_call(L, L->stack.top-nParams-1, nResults);
|
*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.
|
** function position.
|
||||||
** The number of results is nResults, unless nResults=MULT_RET.
|
** The number of results is nResults, unless nResults=MULT_RET.
|
||||||
*/
|
*/
|
||||||
void luaD_call (lua_State *L, TObject *func, int nResults) {
|
void luaD_call (lua_State *L, StkId func, int nResults) {
|
||||||
struct Stack *S = &L->stack; /* to optimize */
|
|
||||||
StkId base = func - S->stack + 1; /* where is first argument */
|
|
||||||
StkId firstResult;
|
StkId firstResult;
|
||||||
switch (ttype(func)) {
|
switch (ttype(func)) {
|
||||||
case LUA_T_CPROTO:
|
case LUA_T_CPROTO:
|
||||||
ttype(func) = LUA_T_CMARK;
|
ttype(func) = LUA_T_CMARK;
|
||||||
firstResult = callC(L, fvalue(func), base);
|
firstResult = callC(L, fvalue(func), func+1);
|
||||||
break;
|
break;
|
||||||
case LUA_T_PROTO:
|
case LUA_T_PROTO:
|
||||||
ttype(func) = LUA_T_PMARK;
|
ttype(func) = LUA_T_PMARK;
|
||||||
firstResult = luaV_execute(L, NULL, tfvalue(func), base);
|
firstResult = luaV_execute(L, NULL, tfvalue(func), func+1);
|
||||||
break;
|
break;
|
||||||
case LUA_T_CLOSURE: {
|
case LUA_T_CLOSURE: {
|
||||||
Closure *c = clvalue(func);
|
Closure *c = clvalue(func);
|
||||||
TObject *proto = c->consts;
|
TObject *proto = c->consts;
|
||||||
ttype(func) = LUA_T_CLMARK;
|
ttype(func) = LUA_T_CLMARK;
|
||||||
firstResult = (ttype(proto) == LUA_T_CPROTO) ?
|
firstResult = (ttype(proto) == LUA_T_CPROTO) ?
|
||||||
callCclosure(L, c, fvalue(proto), base) :
|
callCclosure(L, c, fvalue(proto), func+1) :
|
||||||
luaV_execute(L, c, tfvalue(proto), base);
|
luaV_execute(L, c, tfvalue(proto), func+1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: { /* func is not a function */
|
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);
|
const TObject *im = luaT_getimbyObj(L, func, IM_FUNCTION);
|
||||||
if (ttype(im) == LUA_T_NIL)
|
if (ttype(im) == LUA_T_NIL)
|
||||||
lua_error(L, "call expression not a function");
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* adjust the number of results */
|
/* adjust the number of results */
|
||||||
if (nResults == MULT_RET)
|
if (nResults == MULT_RET)
|
||||||
nResults = (S->top-S->stack)-firstResult;
|
nResults = L->top - firstResult;
|
||||||
else
|
else
|
||||||
luaD_adjusttop(L, firstResult+nResults);
|
luaD_adjusttop(L, firstResult, nResults);
|
||||||
/* move results to base-1 (to erase parameters and function) */
|
/* move results to func (to erase parameters and function) */
|
||||||
base--;
|
luaO_memdown(func, firstResult, nResults*sizeof(TObject));
|
||||||
luaO_memdown(S->stack+base, S->stack+firstResult, nResults*sizeof(TObject));
|
L->top = func+nResults;
|
||||||
S->top -= firstResult-base;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -220,10 +224,10 @@ static void message (lua_State *L, const char *s) {
|
||||||
const TObject *em = &(luaS_assertglobalbyname(L, "_ERRORMESSAGE")->value);
|
const TObject *em = &(luaS_assertglobalbyname(L, "_ERRORMESSAGE")->value);
|
||||||
if (ttype(em) == LUA_T_PROTO || ttype(em) == LUA_T_CPROTO ||
|
if (ttype(em) == LUA_T_PROTO || ttype(em) == LUA_T_CPROTO ||
|
||||||
ttype(em) == LUA_T_CLOSURE) {
|
ttype(em) == LUA_T_CLOSURE) {
|
||||||
*L->stack.top = *em;
|
*L->top = *em;
|
||||||
incr_top;
|
incr_top;
|
||||||
lua_pushstring(L, s);
|
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;
|
L->errorJmp = &myErrorJmp;
|
||||||
if (setjmp(myErrorJmp.b) == 0) {
|
if (setjmp(myErrorJmp.b) == 0) {
|
||||||
StkId base = L->Cstack.base;
|
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.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 */
|
L->Cstack.base = base + L->Cstack.num; /* incorporate results on stack */
|
||||||
status = 0;
|
status = 0;
|
||||||
}
|
}
|
||||||
else { /* an error occurred: restore L->Cstack and L->stack.top */
|
else { /* an error occurred: restore the stack */
|
||||||
L->Cstack = oldCLS;
|
L->Cstack = oldCLS;
|
||||||
L->stack.top = L->stack.stack+L->Cstack.base;
|
L->top = L->Cstack.base;
|
||||||
|
restore_stack_limit(L);
|
||||||
status = 1;
|
status = 1;
|
||||||
}
|
}
|
||||||
L->errorJmp = oldErr;
|
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);
|
tf = bin ? luaU_undump1(L, z) : luaY_parser(L, z);
|
||||||
status = 0;
|
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->Cstack = oldCLS;
|
||||||
L->stack.top = L->stack.stack+L->Cstack.base;
|
L->top = L->Cstack.base;
|
||||||
tf = NULL;
|
tf = NULL;
|
||||||
status = 1;
|
status = 1;
|
||||||
}
|
}
|
||||||
L->errorJmp = oldErr;
|
L->errorJmp = oldErr;
|
||||||
if (status) return 1; /* error code */
|
if (status) return 1; /* error code */
|
||||||
if (tf == NULL) return 2; /* 'natural' end */
|
if (tf == NULL) return 2; /* `natural' end */
|
||||||
luaD_adjusttop(L, L->Cstack.base+1); /* one slot for the pseudo-function */
|
luaD_adjusttop(L, L->Cstack.base, 1); /* one slot for the pseudo-function */
|
||||||
L->stack.stack[L->Cstack.base].ttype = LUA_T_PROTO;
|
L->Cstack.base->ttype = LUA_T_PROTO;
|
||||||
L->stack.stack[L->Cstack.base].value.tf = tf;
|
L->Cstack.base->value.tf = tf;
|
||||||
luaV_closure(L, 0);
|
luaV_closure(L, 0);
|
||||||
return 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) {
|
void luaD_gcIM (lua_State *L, const TObject *o) {
|
||||||
const TObject *im = luaT_getimbyObj(L, o, IM_GC);
|
const TObject *im = luaT_getimbyObj(L, o, IM_GC);
|
||||||
if (ttype(im) != LUA_T_NIL) {
|
if (ttype(im) != LUA_T_NIL) {
|
||||||
*L->stack.top = *o;
|
*L->top = *o;
|
||||||
incr_top;
|
incr_top;
|
||||||
luaD_callTM(L, im, 1, 0);
|
luaD_callTM(L, im, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
18
ldo.h
18
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
|
** Stack and Call structure of Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -20,22 +20,22 @@
|
||||||
** macro to increment stack top.
|
** macro to increment stack top.
|
||||||
** There must be always an empty slot at the L->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); \
|
#define incr_top {if (L->top == L->stack_last) luaD_checkstack(L, 1); L->top++;}
|
||||||
L->stack.top++; }
|
|
||||||
|
|
||||||
|
|
||||||
/* macros to convert from lua_Object to (TObject *) and back */
|
/* macros to convert from lua_Object to (TObject *) and back */
|
||||||
|
|
||||||
#define Address(L, lo) ((lo)+L->stack.stack-1)
|
#define Address(L, lo) ((lo)+L->stack-1)
|
||||||
#define Ref(L, st) ((st)-L->stack.stack+1)
|
#define Ref(L, st) ((st)-L->stack+1)
|
||||||
|
|
||||||
|
|
||||||
void luaD_init (lua_State *L);
|
void luaD_init (lua_State *L);
|
||||||
void luaD_adjusttop (lua_State *L, StkId newtop);
|
void luaD_adjusttop (lua_State *L, StkId base, int extra);
|
||||||
void luaD_openstack (lua_State *L, int nelems);
|
void luaD_openstack (lua_State *L, StkId pos);
|
||||||
void luaD_lineHook (lua_State *L, int line);
|
void luaD_lineHook (lua_State *L, int line);
|
||||||
void luaD_callHook (lua_State *L, StkId base, const TProtoFunc *tf, int isreturn);
|
void luaD_callHook (lua_State *L, StkId base, const TProtoFunc *tf,
|
||||||
void luaD_call (lua_State *L, TObject *func, int nResults);
|
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);
|
void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults);
|
||||||
int luaD_protectedrun (lua_State *L);
|
int luaD_protectedrun (lua_State *L);
|
||||||
void luaD_gcIM (lua_State *L, const TObject *o);
|
void luaD_gcIM (lua_State *L, const TObject *o);
|
||||||
|
|
8
lgc.c
8
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
|
** Garbage Collector
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -77,9 +77,9 @@ static void travglobal (lua_State *L) {
|
||||||
|
|
||||||
|
|
||||||
static void travstack (lua_State *L) {
|
static void travstack (lua_State *L) {
|
||||||
StkId i;
|
int i;
|
||||||
for (i = (L->stack.top-1)-L->stack.stack; i>=0; i--)
|
for (i = (L->top-1)-L->stack; i>=0; i--)
|
||||||
markobject(L, L->stack.stack+i);
|
markobject(L, L->stack+i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
** LL(1) Parser and code generator for Lua
|
||||||
** See Copyright Notice in lua.h
|
** 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 maxstacksize */
|
||||||
code_byte(ls, 0); /* to be filled with arg information */
|
code_byte(ls, 0); /* to be filled with arg information */
|
||||||
/* push function (to avoid GC) */
|
/* push function (to avoid GC) */
|
||||||
tfvalue(L->stack.top) = f;
|
tfvalue(L->top) = f;
|
||||||
ttype(L->stack.top) = LUA_T_PROTO;
|
ttype(L->top) = LUA_T_PROTO;
|
||||||
incr_top;
|
incr_top;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -599,7 +599,7 @@ static void close_func (LexState *ls) {
|
||||||
luaM_reallocvector(ls->L, f->locvars, fs->nvars, LocVar);
|
luaM_reallocvector(ls->L, f->locvars, fs->nvars, LocVar);
|
||||||
}
|
}
|
||||||
ls->fs = fs->prev;
|
ls->fs = fs->prev;
|
||||||
ls->L->stack.top--; /* pop function */
|
ls->L->top--; /* pop function */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
7
lstate.c
7
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
|
** Global State
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -23,9 +23,6 @@ lua_State *lua_state = NULL;
|
||||||
|
|
||||||
lua_State *lua_newstate (void) {
|
lua_State *lua_newstate (void) {
|
||||||
lua_State *L = luaM_new(NULL, lua_State);
|
lua_State *L = luaM_new(NULL, lua_State);
|
||||||
L->Cstack.base = 0;
|
|
||||||
L->Cstack.lua2C = 0;
|
|
||||||
L->Cstack.num = 0;
|
|
||||||
L->errorJmp = NULL;
|
L->errorJmp = NULL;
|
||||||
L->Mbuffer = NULL;
|
L->Mbuffer = NULL;
|
||||||
L->Mbuffbase = 0;
|
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->rootglobal == NULL, "list should be empty");
|
||||||
LUA_ASSERT(L, L->roottable == NULL, "list should be empty");
|
LUA_ASSERT(L, L->roottable == NULL, "list should be empty");
|
||||||
luaS_freeall(L);
|
luaS_freeall(L);
|
||||||
luaM_free(L, L->stack.stack);
|
luaM_free(L, L->stack);
|
||||||
luaM_free(L, L->IMtable);
|
luaM_free(L, L->IMtable);
|
||||||
luaM_free(L, L->refArray);
|
luaM_free(L, L->refArray);
|
||||||
luaM_free(L, L->Mbuffer);
|
luaM_free(L, L->Mbuffer);
|
||||||
|
|
27
lstate.h
27
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
|
** Global State
|
||||||
** See Copyright Notice in lua.h
|
** 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;
|
** stack layout for C point of view:
|
||||||
TObject *stack;
|
** [lua2C, lua2C+num) - `array' lua2C
|
||||||
TObject *last;
|
** [lua2C+num, base) - space for extra lua_Objects
|
||||||
};
|
** [base, L->top) - `stack' C2Lua
|
||||||
|
*/
|
||||||
struct C_Lua_Stack {
|
struct C_Lua_Stack {
|
||||||
StkId base; /* when Lua calls C or C calls Lua, points to */
|
StkId base;
|
||||||
/* the first slot after the last parameter. */
|
StkId lua2C;
|
||||||
StkId lua2C; /* points to first element of "array" lua2C */
|
int num;
|
||||||
int num; /* size of "array" lua2C */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -51,7 +50,9 @@ typedef struct stringtable {
|
||||||
|
|
||||||
struct lua_State {
|
struct lua_State {
|
||||||
/* thread-specific 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 C_Lua_Stack Cstack; /* C2lua struct */
|
||||||
struct lua_longjmp *errorJmp; /* current error recover point */
|
struct lua_longjmp *errorJmp; /* current error recover point */
|
||||||
char *Mbuffer; /* global buffer */
|
char *Mbuffer; /* global buffer */
|
||||||
|
|
351
lvm.c
351
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
|
** Lua virtual machine
|
||||||
** See Copyright Notice in lua.h
|
** 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) {
|
void luaV_closure (lua_State *L, int nelems) {
|
||||||
if (nelems > 0) {
|
if (nelems > 0) {
|
||||||
struct Stack *S = &L->stack;
|
|
||||||
Closure *c = luaF_newclosure(L, nelems);
|
Closure *c = luaF_newclosure(L, nelems);
|
||||||
c->consts[0] = *(S->top-1);
|
c->consts[0] = *(L->top-1);
|
||||||
memcpy(&c->consts[1], S->top-(nelems+1), nelems*sizeof(TObject));
|
L->top -= nelems;
|
||||||
S->top -= nelems;
|
memcpy(&c->consts[1], L->top-1, nelems*sizeof(TObject));
|
||||||
ttype(S->top-1) = LUA_T_CLOSURE;
|
ttype(L->top-1) = LUA_T_CLOSURE;
|
||||||
(S->top-1)->value.cl = c;
|
(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.
|
** Receives the table at top-2 and the index at top-1.
|
||||||
*/
|
*/
|
||||||
void luaV_gettable (lua_State *L) {
|
void luaV_gettable (lua_State *L) {
|
||||||
TObject *table = L->stack.top-2;
|
TObject *table = L->top-2;
|
||||||
const TObject *im;
|
const TObject *im;
|
||||||
if (ttype(table) != LUA_T_ARRAY) { /* not a table, get gettable method */
|
if (ttype(table) != LUA_T_ARRAY) { /* not a table, get gettable method */
|
||||||
im = luaT_getimbyObj(L, table, IM_GETTABLE);
|
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 */
|
luaD_callTM(L, im, 2, 1); /* calls it */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
L->stack.top--;
|
L->top--;
|
||||||
*table = *h; /* "push" result into table position */
|
*table = *h; /* "push" result into table position */
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -132,8 +131,7 @@ void luaV_gettable (lua_State *L) {
|
||||||
/*
|
/*
|
||||||
** Receives table at *t, index at *(t+1) and value at top.
|
** Receives table at *t, index at *(t+1) and value at top.
|
||||||
*/
|
*/
|
||||||
void luaV_settable (lua_State *L, const TObject *t) {
|
void luaV_settable (lua_State *L, StkId t) {
|
||||||
struct Stack *S = &L->stack;
|
|
||||||
const TObject *im;
|
const TObject *im;
|
||||||
if (ttype(t) != LUA_T_ARRAY) { /* not a table, get "settable" method */
|
if (ttype(t) != LUA_T_ARRAY) { /* not a table, get "settable" method */
|
||||||
im = luaT_getimbyObj(L, t, IM_SETTABLE);
|
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... */
|
else { /* object is a table... */
|
||||||
im = luaT_getim(L, avalue(t)->htag, IM_SETTABLE);
|
im = luaT_getim(L, avalue(t)->htag, IM_SETTABLE);
|
||||||
if (ttype(im) == LUA_T_NIL) { /* and does not have a "settable" method */
|
if (ttype(im) == LUA_T_NIL) { /* and does not have a "settable" method */
|
||||||
luaH_set(L, avalue(t), t+1, S->top-1);
|
luaH_set(L, avalue(t), t+1, L->top-1);
|
||||||
S->top--; /* pop value */
|
L->top--; /* pop value */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* else it has a "settable" method, go through to next command */
|
/* else it has a "settable" method, go through to next command */
|
||||||
}
|
}
|
||||||
/* object is not a table, or it has a "settable" method */
|
/* object is not a table, or it has a "settable" method */
|
||||||
/* prepare arguments and call the tag method */
|
/* prepare arguments and call the tag method */
|
||||||
*(S->top+1) = *(L->stack.top-1);
|
*(L->top+1) = *(L->top-1);
|
||||||
*(S->top) = *(t+1);
|
*(L->top) = *(t+1);
|
||||||
*(S->top-1) = *t;
|
*(L->top-1) = *t;
|
||||||
S->top += 2; /* WARNING: caller must assure stack space */
|
L->top += 2; /* WARNING: caller must assure stack space */
|
||||||
luaD_callTM(L, im, 3, 0);
|
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)
|
if (ttype(t) != LUA_T_ARRAY)
|
||||||
lua_error(L, "indexed expression not a table");
|
lua_error(L, "indexed expression not a table");
|
||||||
else {
|
else {
|
||||||
struct Stack *S = &L->stack;
|
luaH_set(L, avalue(t), t+1, L->top-1);
|
||||||
luaH_set(L, avalue(t), t+1, S->top-1);
|
L->top -= 3;
|
||||||
S->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: {
|
case LUA_T_USERDATA: case LUA_T_ARRAY: case LUA_T_NIL: {
|
||||||
TObject *im = luaT_getimbyObj(L, value, IM_GETGLOBAL);
|
TObject *im = luaT_getimbyObj(L, value, IM_GETGLOBAL);
|
||||||
if (ttype(im) != LUA_T_NIL) { /* is there a tag method? */
|
if (ttype(im) != LUA_T_NIL) { /* is there a tag method? */
|
||||||
struct Stack *S = &L->stack;
|
ttype(L->top) = LUA_T_STRING;
|
||||||
ttype(S->top) = LUA_T_STRING;
|
tsvalue(L->top) = gv->name; /* global name */
|
||||||
tsvalue(S->top) = gv->name; /* global name */
|
L->top++;
|
||||||
S->top++;
|
*L->top++ = *value;
|
||||||
*S->top++ = *value;
|
|
||||||
luaD_callTM(L, im, 2, 1);
|
luaD_callTM(L, im, 2, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* else no tag method: go through to default behavior */
|
/* 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 *oldvalue = &gv->value;
|
||||||
const TObject *im = luaT_getimbyObj(L, oldvalue, IM_SETGLOBAL);
|
const TObject *im = luaT_getimbyObj(L, oldvalue, IM_SETGLOBAL);
|
||||||
if (ttype(im) == LUA_T_NIL) /* is there a tag method? */
|
if (ttype(im) == LUA_T_NIL) /* is there a tag method? */
|
||||||
gv->value = *(--L->stack.top);
|
gv->value = *(--L->top);
|
||||||
else {
|
else {
|
||||||
/* WARNING: caller must assure stack space */
|
/* WARNING: caller must assure stack space */
|
||||||
struct Stack *S = &L->stack;
|
|
||||||
TObject newvalue;
|
TObject newvalue;
|
||||||
newvalue = *(S->top-1);
|
newvalue = *(L->top-1);
|
||||||
ttype(S->top-1) = LUA_T_STRING;
|
ttype(L->top-1) = LUA_T_STRING;
|
||||||
tsvalue(S->top-1) = gv->name;
|
tsvalue(L->top-1) = gv->name;
|
||||||
*S->top++ = *oldvalue;
|
*L->top++ = *oldvalue;
|
||||||
*S->top++ = newvalue;
|
*L->top++ = newvalue;
|
||||||
luaD_callTM(L, im, 3, 0);
|
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 */
|
/* 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) {
|
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) {
|
if (ttype(im) == LUA_T_NIL) {
|
||||||
im = luaT_getim(L, 0, event); /* try a 'global' i.m. */
|
im = luaT_getim(L, 0, event); /* try a 'global' i.m. */
|
||||||
if (ttype(im) == LUA_T_NIL)
|
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) {
|
static void call_arith (lua_State *L, StkId top, IMS event) {
|
||||||
call_binTM(L, event, "unexpected type in arithmetic operation");
|
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,
|
void luaV_comparison (lua_State *L, StkId top, lua_Type ttype_less,
|
||||||
lua_Type ttype_great, IMS op) {
|
lua_Type ttype_equal, lua_Type ttype_great, IMS op) {
|
||||||
struct Stack *S = &L->stack;
|
const TObject *l = top-2;
|
||||||
const TObject *l = S->top-2;
|
const TObject *r = top-1;
|
||||||
const TObject *r = S->top-1;
|
|
||||||
real result;
|
real result;
|
||||||
if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER)
|
if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER)
|
||||||
result = nvalue(l)-nvalue(r);
|
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,
|
result = luaV_strcomp(svalue(l), tsvalue(l)->u.s.len,
|
||||||
svalue(r), tsvalue(r)->u.s.len);
|
svalue(r), tsvalue(r)->u.s.len);
|
||||||
else {
|
else {
|
||||||
call_binTM(L, op, "unexpected type in comparison");
|
call_binTM(L, top, op, "unexpected type in comparison");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
S->top--;
|
nvalue(top-2) = 1;
|
||||||
nvalue(S->top-1) = 1;
|
ttype(top-2) = (result < 0) ? ttype_less :
|
||||||
ttype(S->top-1) = (result < 0) ? ttype_less :
|
|
||||||
(result == 0) ? ttype_equal : ttype_great;
|
(result == 0) ? ttype_equal : ttype_great;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaV_pack (lua_State *L, StkId firstel, int nvararg, TObject *tab) {
|
void luaV_pack (lua_State *L, StkId firstelem, int nvararg, TObject *tab) {
|
||||||
TObject *firstelem = L->stack.stack+firstel;
|
|
||||||
int i;
|
int i;
|
||||||
Hash *htab;
|
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;
|
ttype(tab) = LUA_T_ARRAY;
|
||||||
for (i=0; i<nvararg; i++)
|
for (i=0; i<nvararg; i++)
|
||||||
luaH_setint(L, htab, i+1, firstelem+i);
|
luaH_setint(L, htab, i+1, firstelem+i);
|
||||||
luaV_setn(L, htab, nvararg); /* store counter in field "n" */
|
luaV_setn(L, htab, nvararg); /* store counter in field `n' */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void adjust_varargs (lua_State *L, StkId first_extra_arg) {
|
static void adjust_varargs (lua_State *L, StkId base, int nfixargs) {
|
||||||
TObject arg;
|
TObject arg;
|
||||||
luaV_pack(L, first_extra_arg,
|
int nvararg = (L->top-base) - nfixargs;
|
||||||
(L->stack.top-L->stack.stack)-first_extra_arg, &arg);
|
if (nvararg < 0) {
|
||||||
luaD_adjusttop(L, first_extra_arg);
|
luaV_pack(L, base, 0, &arg);
|
||||||
*L->stack.top++ = 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
|
** Execute the given opcode, until a RET. Parameters are between
|
||||||
** [stack+base,top). Returns n such that the the results 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 luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
|
||||||
StkId base) {
|
StkId base) {
|
||||||
struct Stack *S = &L->stack; /* to optimize */
|
register StkId top; /* keep top local, for performance */
|
||||||
register const Byte *pc = tf->code;
|
register const Byte *pc = tf->code;
|
||||||
const TObject *consts = tf->consts;
|
const TObject *consts = tf->consts;
|
||||||
if (L->callhook)
|
if (L->callhook)
|
||||||
luaD_callHook(L, base, tf, 0);
|
luaD_callHook(L, base, tf, 0);
|
||||||
luaD_checkstack(L, (*pc++)+EXTRA_STACK);
|
luaD_checkstack(L, (*pc++)+EXTRA_STACK);
|
||||||
if (*pc < ZEROVARARG)
|
if (*pc < ZEROVARARG)
|
||||||
luaD_adjusttop(L, base+*(pc++));
|
luaD_adjusttop(L, base, *(pc++));
|
||||||
else { /* varargs */
|
else { /* varargs */
|
||||||
|
adjust_varargs(L, base, (*pc++)-ZEROVARARG);
|
||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
adjust_varargs(L, base+(*pc++)-ZEROVARARG);
|
|
||||||
}
|
}
|
||||||
|
top = L->top;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
register int aux = 0;
|
register int aux = 0;
|
||||||
switchentry:
|
switchentry:
|
||||||
switch ((OpCode)*pc++) {
|
switch ((OpCode)*pc++) {
|
||||||
|
|
||||||
case ENDCODE:
|
case ENDCODE:
|
||||||
S->top = S->stack + base;
|
top = base;
|
||||||
goto ret;
|
goto ret;
|
||||||
|
|
||||||
case RETCODE:
|
case RETCODE:
|
||||||
|
@ -327,238 +325,240 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
|
||||||
goto ret;
|
goto ret;
|
||||||
|
|
||||||
case CALL: aux = *pc++;
|
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;
|
break;
|
||||||
|
|
||||||
case TAILCALL: aux = *pc++;
|
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;
|
base += aux;
|
||||||
goto ret;
|
goto ret;
|
||||||
|
|
||||||
case PUSHNIL: aux = *pc++;
|
case PUSHNIL: aux = *pc++;
|
||||||
do {
|
do {
|
||||||
ttype(S->top++) = LUA_T_NIL;
|
ttype(top++) = LUA_T_NIL;
|
||||||
} while (aux--);
|
} while (aux--);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case POP: aux = *pc++;
|
case POP: aux = *pc++;
|
||||||
S->top -= aux;
|
top -= aux;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PUSHNUMBERW: aux += highbyte(L, *pc++);
|
case PUSHNUMBERW: aux += highbyte(L, *pc++);
|
||||||
case PUSHNUMBER: aux += *pc++;
|
case PUSHNUMBER: aux += *pc++;
|
||||||
ttype(S->top) = LUA_T_NUMBER;
|
ttype(top) = LUA_T_NUMBER;
|
||||||
nvalue(S->top) = aux;
|
nvalue(top) = aux;
|
||||||
S->top++;
|
top++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PUSHNUMBERNEGW: aux += highbyte(L, *pc++);
|
case PUSHNUMBERNEGW: aux += highbyte(L, *pc++);
|
||||||
case PUSHNUMBERNEG: aux += *pc++;
|
case PUSHNUMBERNEG: aux += *pc++;
|
||||||
ttype(S->top) = LUA_T_NUMBER;
|
ttype(top) = LUA_T_NUMBER;
|
||||||
nvalue(S->top) = -aux;
|
nvalue(top) = -aux;
|
||||||
S->top++;
|
top++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PUSHCONSTANTW: aux += highbyte(L, *pc++);
|
case PUSHCONSTANTW: aux += highbyte(L, *pc++);
|
||||||
case PUSHCONSTANT: aux += *pc++;
|
case PUSHCONSTANT: aux += *pc++;
|
||||||
*S->top++ = consts[aux];
|
*top++ = consts[aux];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PUSHUPVALUE: aux = *pc++;
|
case PUSHUPVALUE: aux = *pc++;
|
||||||
*S->top++ = cl->consts[aux+1];
|
*top++ = cl->consts[aux+1];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PUSHLOCAL: aux = *pc++;
|
case PUSHLOCAL: aux = *pc++;
|
||||||
*S->top++ = *((S->stack+base) + aux);
|
*top++ = *(base+aux);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GETGLOBALW: aux += highbyte(L, *pc++);
|
case GETGLOBALW: aux += highbyte(L, *pc++);
|
||||||
case GETGLOBAL: aux += *pc++;
|
case GETGLOBAL: aux += *pc++;
|
||||||
|
L->top = top;
|
||||||
luaV_getglobal(L, tsvalue(&consts[aux])->u.s.gv);
|
luaV_getglobal(L, tsvalue(&consts[aux])->u.s.gv);
|
||||||
|
top++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GETTABLE:
|
case GETTABLE:
|
||||||
|
L->top = top;
|
||||||
luaV_gettable(L);
|
luaV_gettable(L);
|
||||||
|
top--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GETDOTTEDW: aux += highbyte(L, *pc++);
|
case GETDOTTEDW: aux += highbyte(L, *pc++);
|
||||||
case GETDOTTED: aux += *pc++;
|
case GETDOTTED: aux += *pc++;
|
||||||
*S->top++ = consts[aux];
|
*top++ = consts[aux];
|
||||||
|
L->top = top;
|
||||||
luaV_gettable(L);
|
luaV_gettable(L);
|
||||||
|
top--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PUSHSELFW: aux += highbyte(L, *pc++);
|
case PUSHSELFW: aux += highbyte(L, *pc++);
|
||||||
case PUSHSELF: aux += *pc++; {
|
case PUSHSELF: aux += *pc++; {
|
||||||
TObject receiver;
|
TObject receiver;
|
||||||
receiver = *(S->top-1);
|
receiver = *(top-1);
|
||||||
*S->top++ = consts[aux];
|
*top++ = consts[aux];
|
||||||
|
L->top = top;
|
||||||
luaV_gettable(L);
|
luaV_gettable(L);
|
||||||
*S->top++ = receiver;
|
*(top-1) = receiver;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CREATEARRAYW: aux += highbyte(L, *pc++);
|
case CREATEARRAYW: aux += highbyte(L, *pc++);
|
||||||
case CREATEARRAY: aux += *pc++;
|
case CREATEARRAY: aux += *pc++;
|
||||||
|
L->top = top;
|
||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
avalue(S->top) = luaH_new(L, aux);
|
avalue(top) = luaH_new(L, aux);
|
||||||
ttype(S->top) = LUA_T_ARRAY;
|
ttype(top) = LUA_T_ARRAY;
|
||||||
S->top++;
|
top++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SETLOCAL: aux = *pc++;
|
case SETLOCAL: aux = *pc++;
|
||||||
*((S->stack+base) + aux) = *(--S->top);
|
*(base+aux) = *(--top);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SETGLOBALW: aux += highbyte(L, *pc++);
|
case SETGLOBALW: aux += highbyte(L, *pc++);
|
||||||
case SETGLOBAL: aux += *pc++;
|
case SETGLOBAL: aux += *pc++;
|
||||||
|
L->top = top;
|
||||||
luaV_setglobal(L, tsvalue(&consts[aux])->u.s.gv);
|
luaV_setglobal(L, tsvalue(&consts[aux])->u.s.gv);
|
||||||
|
top--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SETTABLEPOP:
|
case SETTABLEPOP:
|
||||||
luaV_settable(L, S->top-3);
|
L->top = top;
|
||||||
S->top -= 2; /* pop table and index */
|
luaV_settable(L, top-3);
|
||||||
|
top -= 3; /* pop table, index, and value */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SETTABLE:
|
case SETTABLE:
|
||||||
luaV_settable(L, S->top-3-(*pc++));
|
L->top = top;
|
||||||
|
luaV_settable(L, top-3-(*pc++));
|
||||||
|
top--; /* pop value */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SETLISTW: aux += highbyte(L, *pc++);
|
case SETLISTW: aux += highbyte(L, *pc++);
|
||||||
case SETLIST: aux += *pc++; {
|
case SETLIST: aux += *pc++; {
|
||||||
int n = *(pc++);
|
int n = *(pc++);
|
||||||
Hash *arr = avalue(S->top-n-1);
|
Hash *arr = avalue(top-n-1);
|
||||||
aux *= LFIELDS_PER_FLUSH;
|
aux *= LFIELDS_PER_FLUSH;
|
||||||
for (; n; n--)
|
for (; n; n--)
|
||||||
luaH_setint(L, arr, n+aux, --S->top);
|
luaH_setint(L, arr, n+aux, --top);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SETMAP: aux = *pc++; {
|
case SETMAP: aux = *pc++; {
|
||||||
Hash *arr = avalue(S->top-(2*aux)-3);
|
Hash *arr = avalue(top-(2*aux)-3);
|
||||||
do {
|
do {
|
||||||
luaH_set(L, arr, S->top-2, S->top-1);
|
luaH_set(L, arr, top-2, top-1);
|
||||||
S->top-=2;
|
top-=2;
|
||||||
} while (aux--);
|
} while (aux--);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case NEQOP: aux = 1;
|
case NEQOP: aux = 1;
|
||||||
case EQOP: {
|
case EQOP: {
|
||||||
int res = luaO_equalObj(S->top-2, S->top-1);
|
int res = luaO_equalObj(top-2, top-1);
|
||||||
if (aux) res = !res;
|
if (aux) res = !res;
|
||||||
S->top--;
|
top--;
|
||||||
ttype(S->top-1) = res ? LUA_T_NUMBER : LUA_T_NIL;
|
ttype(top-1) = res ? LUA_T_NUMBER : LUA_T_NIL;
|
||||||
nvalue(S->top-1) = 1;
|
nvalue(top-1) = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case LTOP:
|
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;
|
break;
|
||||||
|
|
||||||
case LEOP:
|
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;
|
break;
|
||||||
|
|
||||||
case GTOP:
|
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;
|
break;
|
||||||
|
|
||||||
case GEOP:
|
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;
|
break;
|
||||||
|
|
||||||
case ADDOP: {
|
case ADDOP:
|
||||||
TObject *l = S->top-2;
|
if (tonumber(top-1) || tonumber(top-2))
|
||||||
TObject *r = S->top-1;
|
call_arith(L, top, IM_ADD);
|
||||||
if (tonumber(r) || tonumber(l))
|
else
|
||||||
call_arith(L, IM_ADD);
|
nvalue(top-2) += nvalue(top-1);
|
||||||
else {
|
top--;
|
||||||
nvalue(l) += nvalue(r);
|
|
||||||
--S->top;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case SUBOP: {
|
case SUBOP:
|
||||||
TObject *l = S->top-2;
|
if (tonumber(top-1) || tonumber(top-2))
|
||||||
TObject *r = S->top-1;
|
call_arith(L, top, IM_SUB);
|
||||||
if (tonumber(r) || tonumber(l))
|
else
|
||||||
call_arith(L, IM_SUB);
|
nvalue(top-2) -= nvalue(top-1);
|
||||||
else {
|
top--;
|
||||||
nvalue(l) -= nvalue(r);
|
|
||||||
--S->top;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case MULTOP: {
|
case MULTOP:
|
||||||
TObject *l = S->top-2;
|
if (tonumber(top-1) || tonumber(top-2))
|
||||||
TObject *r = S->top-1;
|
call_arith(L, top, IM_MUL);
|
||||||
if (tonumber(r) || tonumber(l))
|
else
|
||||||
call_arith(L, IM_MUL);
|
nvalue(top-2) *= nvalue(top-1);
|
||||||
else {
|
top--;
|
||||||
nvalue(l) *= nvalue(r);
|
|
||||||
--S->top;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case DIVOP: {
|
case DIVOP:
|
||||||
TObject *l = S->top-2;
|
if (tonumber(top-1) || tonumber(top-2))
|
||||||
TObject *r = S->top-1;
|
call_arith(L, top, IM_DIV);
|
||||||
if (tonumber(r) || tonumber(l))
|
else
|
||||||
call_arith(L, IM_DIV);
|
nvalue(top-2) /= nvalue(top-1);
|
||||||
else {
|
top--;
|
||||||
nvalue(l) /= nvalue(r);
|
|
||||||
--S->top;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case POWOP:
|
case POWOP:
|
||||||
call_binTM(L, IM_POW, "undefined operation");
|
call_binTM(L, top, IM_POW, "undefined operation");
|
||||||
|
top--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CONCOP: {
|
case CONCOP:
|
||||||
TObject *l = S->top-2;
|
if (tostring(L, top-2) || tostring(L, top-1))
|
||||||
TObject *r = S->top-1;
|
call_binTM(L, top, IM_CONCAT, "unexpected type for concatenation");
|
||||||
if (tostring(L, l) || tostring(L, r))
|
else
|
||||||
call_binTM(L, IM_CONCAT, "unexpected type for concatenation");
|
tsvalue(top-2) = strconc(L, tsvalue(top-2), tsvalue(top-1));
|
||||||
else {
|
L->top = top;
|
||||||
tsvalue(l) = strconc(L, tsvalue(l), tsvalue(r));
|
|
||||||
--S->top;
|
|
||||||
}
|
|
||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
|
top--;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case MINUSOP:
|
case MINUSOP:
|
||||||
if (tonumber(S->top-1)) {
|
if (tonumber(top-1)) {
|
||||||
ttype(S->top) = LUA_T_NIL;
|
ttype(top) = LUA_T_NIL;
|
||||||
S->top++;
|
call_arith(L, top+1, IM_UNM);
|
||||||
call_arith(L, IM_UNM);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
nvalue(S->top-1) = - nvalue(S->top-1);
|
nvalue(top-1) = - nvalue(top-1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NOTOP:
|
case NOTOP:
|
||||||
ttype(S->top-1) =
|
ttype(top-1) =
|
||||||
(ttype(S->top-1) == LUA_T_NIL) ? LUA_T_NUMBER : LUA_T_NIL;
|
(ttype(top-1) == LUA_T_NIL) ? LUA_T_NUMBER : LUA_T_NIL;
|
||||||
nvalue(S->top-1) = 1;
|
nvalue(top-1) = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ONTJMPW: aux += highbyte(L, *pc++);
|
case ONTJMPW: aux += highbyte(L, *pc++);
|
||||||
case ONTJMP: aux += *pc++;
|
case ONTJMP: aux += *pc++;
|
||||||
if (ttype(S->top-1) != LUA_T_NIL) pc += aux;
|
if (ttype(top-1) != LUA_T_NIL) pc += aux;
|
||||||
else S->top--;
|
else top--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ONFJMPW: aux += highbyte(L, *pc++);
|
case ONFJMPW: aux += highbyte(L, *pc++);
|
||||||
case ONFJMP: aux += *pc++;
|
case ONFJMP: aux += *pc++;
|
||||||
if (ttype(S->top-1) == LUA_T_NIL) pc += aux;
|
if (ttype(top-1) == LUA_T_NIL) pc += aux;
|
||||||
else S->top--;
|
else top--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JMPW: aux += highbyte(L, *pc++);
|
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 IFFJMPW: aux += highbyte(L, *pc++);
|
||||||
case IFFJMP: aux += *pc++;
|
case IFFJMP: aux += *pc++;
|
||||||
if (ttype(--S->top) == LUA_T_NIL) pc += aux;
|
if (ttype(--top) == LUA_T_NIL) pc += aux;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IFTUPJMPW: aux += highbyte(L, *pc++);
|
case IFTUPJMPW: aux += highbyte(L, *pc++);
|
||||||
case IFTUPJMP: aux += *pc++;
|
case IFTUPJMP: aux += *pc++;
|
||||||
if (ttype(--S->top) != LUA_T_NIL) pc -= aux;
|
if (ttype(--top) != LUA_T_NIL) pc -= aux;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IFFUPJMPW: aux += highbyte(L, *pc++);
|
case IFFUPJMPW: aux += highbyte(L, *pc++);
|
||||||
case IFFUPJMP: aux += *pc++;
|
case IFFUPJMP: aux += *pc++;
|
||||||
if (ttype(--S->top) == LUA_T_NIL) pc -= aux;
|
if (ttype(--top) == LUA_T_NIL) pc -= aux;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CLOSUREW: aux += highbyte(L, *pc++);
|
case CLOSUREW: aux += highbyte(L, *pc++);
|
||||||
case CLOSURE: aux += *pc++;
|
case CLOSURE: aux += *pc++;
|
||||||
*S->top++ = consts[aux];
|
*top++ = consts[aux];
|
||||||
luaV_closure(L, *pc++);
|
L->top = top;
|
||||||
|
aux = *pc++;
|
||||||
|
luaV_closure(L, aux);
|
||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
|
top -= aux;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SETLINEW: aux += highbyte(L, *pc++);
|
case SETLINEW: aux += highbyte(L, *pc++);
|
||||||
case SETLINE: aux += *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 */
|
/* open space for LINE value */
|
||||||
luaD_openstack(L, (S->top-S->stack)-base);
|
luaD_openstack(L, base);
|
||||||
|
base->ttype = LUA_T_LINE;
|
||||||
base++;
|
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)
|
if (L->linehook)
|
||||||
luaD_lineHook(L, aux);
|
luaD_lineHook(L, aux);
|
||||||
break;
|
break;
|
||||||
|
@ -608,8 +613,8 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
|
||||||
|
|
||||||
}
|
}
|
||||||
} ret:
|
} ret:
|
||||||
|
L->top = top;
|
||||||
if (L->callhook)
|
if (L->callhook)
|
||||||
luaD_callHook(L, 0, NULL, 1);
|
luaD_callHook(L, 0, NULL, 1);
|
||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
lvm.h
10
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
|
** Lua virtual machine
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
|
@ -22,13 +22,13 @@ int luaV_tonumber (TObject *obj);
|
||||||
int luaV_tostring (lua_State *L, TObject *obj);
|
int luaV_tostring (lua_State *L, TObject *obj);
|
||||||
void luaV_setn (lua_State *L, Hash *t, int val);
|
void luaV_setn (lua_State *L, Hash *t, int val);
|
||||||
void luaV_gettable (lua_State *L);
|
void luaV_gettable (lua_State *L);
|
||||||
void luaV_settable (lua_State *L, const TObject *t);
|
void luaV_settable (lua_State *L, StkId t);
|
||||||
void luaV_rawsettable (lua_State *L, const TObject *t);
|
void luaV_rawsettable (lua_State *L, StkId t);
|
||||||
void luaV_getglobal (lua_State *L, GlobalVar *gv);
|
void luaV_getglobal (lua_State *L, GlobalVar *gv);
|
||||||
void luaV_setglobal (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);
|
StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, StkId base);
|
||||||
void luaV_closure (lua_State *L, int nelems);
|
void luaV_closure (lua_State *L, int nelems);
|
||||||
void luaV_comparison (lua_State *L, lua_Type ttype_less, lua_Type ttype_equal,
|
void luaV_comparison (lua_State *L, StkId top, lua_Type ttype_less,
|
||||||
lua_Type ttype_great, IMS op);
|
lua_Type ttype_equal, lua_Type ttype_great, IMS op);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue