mirror of
https://github.com/lua/lua
synced 2024-11-25 22:29:39 +03:00
tag system replaced by event tables
This commit is contained in:
parent
413fc7334b
commit
592a309177
150
lapi.c
150
lapi.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lapi.c,v 1.160 2001/11/16 16:29:51 roberto Exp $
|
||||
** $Id: lapi.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
|
||||
** Lua API
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -45,8 +45,8 @@ static TObject *negindex (lua_State *L, int index) {
|
||||
return L->top+index;
|
||||
}
|
||||
else switch (index) { /* pseudo-indices */
|
||||
case LUA_REGISTRYINDEX: return &G(L)->registry;
|
||||
case LUA_GLOBALSINDEX: return &L->gt;
|
||||
case LUA_REGISTRYINDEX: return registry(L);
|
||||
case LUA_GLOBALSINDEX: return gt(L);
|
||||
default: {
|
||||
TObject *func = (L->ci->base - 1);
|
||||
index = LUA_GLOBALSINDEX - index;
|
||||
@ -149,20 +149,15 @@ LUA_API void lua_pushvalue (lua_State *L, int index) {
|
||||
*/
|
||||
|
||||
|
||||
LUA_API int lua_rawtag (lua_State *L, int index) {
|
||||
LUA_API int lua_type (lua_State *L, int index) {
|
||||
StkId o = luaA_indexAcceptable(L, index);
|
||||
return (o == NULL) ? LUA_TNONE : ttype(o);
|
||||
}
|
||||
|
||||
|
||||
LUA_API const char *lua_type (lua_State *L, int index) {
|
||||
StkId o;
|
||||
const char *type;
|
||||
lua_lock(L);
|
||||
o = luaA_indexAcceptable(L, index);
|
||||
type = (o == NULL) ? "no value" : luaT_typename(G(L), o);
|
||||
lua_unlock(L);
|
||||
return type;
|
||||
LUA_API const char *lua_typename (lua_State *L, int t) {
|
||||
UNUSED(L);
|
||||
return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
|
||||
}
|
||||
|
||||
|
||||
@ -180,22 +175,11 @@ LUA_API int lua_isnumber (lua_State *L, int index) {
|
||||
|
||||
|
||||
LUA_API int lua_isstring (lua_State *L, int index) {
|
||||
int t = lua_rawtag(L, index);
|
||||
int t = lua_type(L, index);
|
||||
return (t == LUA_TSTRING || t == LUA_TNUMBER);
|
||||
}
|
||||
|
||||
|
||||
LUA_API int lua_tag (lua_State *L, int index) {
|
||||
StkId o;
|
||||
int i;
|
||||
lua_lock(L); /* other thread could be changing the tag */
|
||||
o = luaA_indexAcceptable(L, index);
|
||||
i = (o == NULL) ? LUA_NOTAG : luaT_tag(o);
|
||||
lua_unlock(L);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
LUA_API int lua_equal (lua_State *L, int index1, int index2) {
|
||||
StkId o1 = luaA_indexAcceptable(L, index1);
|
||||
StkId o2 = luaA_indexAcceptable(L, index2);
|
||||
@ -346,8 +330,10 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
|
||||
|
||||
|
||||
LUA_API void lua_getglobal (lua_State *L, const char *name) {
|
||||
TObject o;
|
||||
lua_lock(L);
|
||||
luaV_getglobal(L, luaS_new(L, name), L->top);
|
||||
setsvalue(&o, luaS_new(L, name));
|
||||
luaV_gettable(L, gt(L), &o, L->top);
|
||||
api_incr_top(L);
|
||||
lua_unlock(L);
|
||||
}
|
||||
@ -391,6 +377,29 @@ LUA_API void lua_newtable (lua_State *L) {
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_geteventtable (lua_State *L, int objindex) {
|
||||
StkId obj;
|
||||
Table *et;
|
||||
lua_lock(L);
|
||||
obj = luaA_indexAcceptable(L, objindex);
|
||||
switch (ttype(obj)) {
|
||||
case LUA_TTABLE:
|
||||
et = hvalue(obj)->eventtable;
|
||||
break;
|
||||
case LUA_TUSERDATA:
|
||||
et = uvalue(obj)->uv.eventtable;
|
||||
break;
|
||||
default:
|
||||
et = hvalue(defaultet(L));
|
||||
}
|
||||
if (et == hvalue(defaultet(L)))
|
||||
setnilvalue(L->top);
|
||||
else
|
||||
sethvalue(L->top, et);
|
||||
api_incr_top(L);
|
||||
lua_unlock(L);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** set functions (stack -> Lua)
|
||||
@ -398,9 +407,11 @@ LUA_API void lua_newtable (lua_State *L) {
|
||||
|
||||
|
||||
LUA_API void lua_setglobal (lua_State *L, const char *name) {
|
||||
TObject o;
|
||||
lua_lock(L);
|
||||
api_checknelems(L, 1);
|
||||
luaV_setglobal(L, luaS_new(L, name), L->top - 1);
|
||||
setsvalue(&o, luaS_new(L, name));
|
||||
luaV_settable(L, gt(L), &o, L->top - 1);
|
||||
L->top--; /* remove element from the top */
|
||||
lua_unlock(L);
|
||||
}
|
||||
@ -447,11 +458,32 @@ LUA_API void lua_setglobals (lua_State *L) {
|
||||
api_checknelems(L, 1);
|
||||
newtable = --L->top;
|
||||
api_check(L, ttype(newtable) == LUA_TTABLE);
|
||||
setobj(&L->gt, newtable);
|
||||
setobj(gt(L), newtable);
|
||||
lua_unlock(L);
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_seteventtable (lua_State *L, int objindex) {
|
||||
StkId obj, et;
|
||||
lua_lock(L);
|
||||
api_checknelems(L, 1);
|
||||
obj = luaA_indexAcceptable(L, objindex);
|
||||
et = --L->top;
|
||||
api_check(L, ttype(et) == LUA_TTABLE);
|
||||
switch (ttype(obj)) {
|
||||
case LUA_TTABLE:
|
||||
hvalue(obj)->eventtable = hvalue(et);
|
||||
break;
|
||||
case LUA_TUSERDATA:
|
||||
uvalue(obj)->uv.eventtable = hvalue(et);
|
||||
break;
|
||||
default:
|
||||
luaO_verror(L, "cannot change the event table of a %.20s",
|
||||
luaT_typenames[ttype(obj)]);
|
||||
}
|
||||
lua_unlock(L);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** `do' functions (run Lua code)
|
||||
@ -533,70 +565,6 @@ LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) {
|
||||
** miscellaneous functions
|
||||
*/
|
||||
|
||||
LUA_API int lua_newtype (lua_State *L, const char *name, int basictype) {
|
||||
int tag;
|
||||
lua_lock(L);
|
||||
if (basictype != LUA_TNONE &&
|
||||
basictype != LUA_TTABLE &&
|
||||
basictype != LUA_TUSERDATA)
|
||||
luaO_verror(L, "invalid basic type (%d) for new type", basictype);
|
||||
tag = luaT_newtag(L, name, basictype);
|
||||
if (tag == LUA_TNONE)
|
||||
luaO_verror(L, "type name '%.30s' already exists", name);
|
||||
lua_unlock(L);
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
||||
LUA_API int lua_name2tag (lua_State *L, const char *name) {
|
||||
int tag;
|
||||
const TObject *v;
|
||||
lua_lock(L);
|
||||
v = luaH_getstr(G(L)->type2tag, luaS_new(L, name));
|
||||
if (ttype(v) == LUA_TNIL)
|
||||
tag = LUA_TNONE;
|
||||
else {
|
||||
lua_assert(ttype(v) == LUA_TNUMBER);
|
||||
tag = cast(int, nvalue(v));
|
||||
}
|
||||
lua_unlock(L);
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
||||
LUA_API const char *lua_tag2name (lua_State *L, int tag) {
|
||||
const char *s;
|
||||
lua_lock(L);
|
||||
s = (tag == LUA_TNONE) ? "no value" : typenamebytag(G(L), tag);
|
||||
lua_unlock(L);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_settag (lua_State *L, int tag) {
|
||||
int basictype;
|
||||
lua_lock(L);
|
||||
api_checknelems(L, 1);
|
||||
if (tag < 0 || tag >= G(L)->ntag)
|
||||
luaO_verror(L, "%d is not a valid tag", tag);
|
||||
basictype = G(L)->TMtable[tag].basictype;
|
||||
if (basictype != LUA_TNONE && basictype != ttype(L->top-1))
|
||||
luaO_verror(L, "tag %d can only be used for type '%.20s'", tag,
|
||||
typenamebytag(G(L), basictype));
|
||||
switch (ttype(L->top-1)) {
|
||||
case LUA_TTABLE:
|
||||
hvalue(L->top-1)->htag = tag;
|
||||
break;
|
||||
case LUA_TUSERDATA:
|
||||
uvalue(L->top-1)->uv.tag = tag;
|
||||
break;
|
||||
default:
|
||||
luaO_verror(L, "cannot change the tag of a %.20s",
|
||||
luaT_typename(G(L), L->top-1));
|
||||
}
|
||||
lua_unlock(L);
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_error (lua_State *L, const char *s) {
|
||||
lua_lock(L);
|
||||
|
19
lauxlib.c
19
lauxlib.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lauxlib.c,v 1.53 2001/10/31 19:40:14 roberto Exp $
|
||||
** $Id: lauxlib.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
|
||||
** Auxiliary functions for building Lua libraries
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -43,7 +43,8 @@ LUALIB_API void luaL_argerror (lua_State *L, int narg, const char *extramsg) {
|
||||
|
||||
LUALIB_API void luaL_typerror (lua_State *L, int narg, const char *tname) {
|
||||
char buff[80];
|
||||
sprintf(buff, "%.25s expected, got %.25s", tname, lua_type(L,narg));
|
||||
sprintf(buff, "%.25s expected, got %.25s", tname,
|
||||
lua_typename(L, lua_type(L,narg)));
|
||||
luaL_argerror(L, narg, buff);
|
||||
}
|
||||
|
||||
@ -59,26 +60,18 @@ LUALIB_API void luaL_check_stack (lua_State *L, int space, const char *mes) {
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API void luaL_check_rawtype(lua_State *L, int narg, int t) {
|
||||
if (lua_rawtag(L, narg) != t)
|
||||
LUALIB_API void luaL_check_type(lua_State *L, int narg, int t) {
|
||||
if (lua_type(L, narg) != t)
|
||||
tag_error(L, narg, t);
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API void luaL_check_any (lua_State *L, int narg) {
|
||||
if (lua_rawtag(L, narg) == LUA_TNONE)
|
||||
if (lua_type(L, narg) == LUA_TNONE)
|
||||
luaL_argerror(L, narg, "value expected");
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API void *luaL_check_userdata (lua_State *L, int narg,
|
||||
const char *name) {
|
||||
if (strcmp(lua_type(L, narg), name) != 0)
|
||||
luaL_typerror(L, narg, name);
|
||||
return lua_touserdata(L, narg);
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API const char *luaL_check_lstr (lua_State *L, int narg, size_t *len) {
|
||||
const char *s = lua_tostring(L, narg);
|
||||
if (!s) tag_error(L, narg, LUA_TSTRING);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lauxlib.h,v 1.38 2001/10/31 19:40:14 roberto Exp $
|
||||
** $Id: lauxlib.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
|
||||
** Auxiliary functions for building Lua libraries
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -38,10 +38,8 @@ LUALIB_API lua_Number luaL_check_number (lua_State *L, int numArg);
|
||||
LUALIB_API lua_Number luaL_opt_number (lua_State *L, int nArg, lua_Number def);
|
||||
|
||||
LUALIB_API void luaL_check_stack (lua_State *L, int space, const char *msg);
|
||||
LUALIB_API void luaL_check_rawtype (lua_State *L, int narg, int t);
|
||||
LUALIB_API void luaL_check_type (lua_State *L, int narg, int t);
|
||||
LUALIB_API void luaL_check_any (lua_State *L, int narg);
|
||||
LUALIB_API void *luaL_check_userdata (lua_State *L, int narg,
|
||||
const char *name);
|
||||
|
||||
LUALIB_API void luaL_verror (lua_State *L, const char *fmt, ...);
|
||||
LUALIB_API int luaL_findstring (const char *name,
|
||||
|
138
lbaselib.c
138
lbaselib.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lbaselib.c,v 1.45 2001/10/26 17:33:30 roberto Exp $
|
||||
** $Id: lbaselib.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
|
||||
** Basic library
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -41,7 +41,7 @@ static int luaB__ALERT (lua_State *L) {
|
||||
** The library `liolib' redefines _ERRORMESSAGE for better error information.
|
||||
*/
|
||||
static int luaB__ERRORMESSAGE (lua_State *L) {
|
||||
luaL_check_rawtype(L, 1, LUA_TSTRING);
|
||||
luaL_check_type(L, 1, LUA_TSTRING);
|
||||
lua_getglobal(L, LUA_ALERT);
|
||||
if (lua_isfunction(L, -1)) { /* avoid error loop if _ALERT is not defined */
|
||||
lua_Debug ar;
|
||||
@ -136,41 +136,22 @@ static int luaB_getglobal (lua_State *L) {
|
||||
}
|
||||
|
||||
|
||||
/* auxiliary function to get `tags' */
|
||||
static int gettag (lua_State *L, int narg) {
|
||||
switch (lua_rawtag(L, narg)) {
|
||||
case LUA_TNUMBER:
|
||||
return (int)(lua_tonumber(L, narg));
|
||||
case LUA_TSTRING: {
|
||||
const char *name = lua_tostring(L, narg);
|
||||
int tag = lua_name2tag(L, name);
|
||||
if (tag == LUA_TNONE)
|
||||
luaL_verror(L, "'%.30s' is not a valid type name", name);
|
||||
return tag;
|
||||
}
|
||||
default:
|
||||
luaL_argerror(L, narg, "tag or type name expected");
|
||||
return 0; /* to avoid warnings */
|
||||
static int luaB_eventtable (lua_State *L) {
|
||||
luaL_check_type(L, 1, LUA_TTABLE);
|
||||
if (lua_isnull(L, 2))
|
||||
lua_geteventtable(L, 1);
|
||||
else {
|
||||
lua_settop(L, 2);
|
||||
luaL_check_type(L, 2, LUA_TTABLE);
|
||||
lua_seteventtable(L, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int luaB_tag (lua_State *L) {
|
||||
luaL_check_any(L, 1);
|
||||
lua_pushnumber(L, lua_tag(L, 1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int luaB_settype (lua_State *L) {
|
||||
luaL_check_rawtype(L, 1, LUA_TTABLE);
|
||||
lua_pushvalue(L, 1); /* push table */
|
||||
lua_settag(L, gettag(L, 2));
|
||||
return 1; /* return table */
|
||||
}
|
||||
|
||||
static int luaB_weakmode (lua_State *L) {
|
||||
const char *mode = luaL_check_string(L, 2);
|
||||
luaL_check_rawtype(L, 1, LUA_TTABLE);
|
||||
luaL_check_type(L, 1, LUA_TTABLE);
|
||||
if (*mode == '?') {
|
||||
char buff[3];
|
||||
char *s = buff;
|
||||
@ -191,17 +172,11 @@ static int luaB_weakmode (lua_State *L) {
|
||||
}
|
||||
}
|
||||
|
||||
static int luaB_newtype (lua_State *L) {
|
||||
const char *name = luaL_opt_string(L, 1, NULL);
|
||||
lua_pushnumber(L, lua_newtype(L, name, LUA_TTABLE));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int luaB_globals (lua_State *L) {
|
||||
lua_getglobals(L); /* value to be returned */
|
||||
if (!lua_isnull(L, 1)) {
|
||||
luaL_check_rawtype(L, 1, LUA_TTABLE);
|
||||
luaL_check_type(L, 1, LUA_TTABLE);
|
||||
lua_pushvalue(L, 1); /* new table of globals */
|
||||
lua_setglobals(L);
|
||||
}
|
||||
@ -209,43 +184,20 @@ static int luaB_globals (lua_State *L) {
|
||||
}
|
||||
|
||||
static int luaB_rawget (lua_State *L) {
|
||||
luaL_check_rawtype(L, 1, LUA_TTABLE);
|
||||
luaL_check_type(L, 1, LUA_TTABLE);
|
||||
luaL_check_any(L, 2);
|
||||
lua_rawget(L, -2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int luaB_rawset (lua_State *L) {
|
||||
luaL_check_rawtype(L, 1, LUA_TTABLE);
|
||||
luaL_check_type(L, 1, LUA_TTABLE);
|
||||
luaL_check_any(L, 2);
|
||||
luaL_check_any(L, 3);
|
||||
lua_rawset(L, -3);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int luaB_settagmethod (lua_State *L) {
|
||||
int tag = gettag(L, 1);
|
||||
const char *event = luaL_check_string(L, 2);
|
||||
luaL_arg_check(L, lua_isfunction(L, 3) || lua_isnil(L, 3), 3,
|
||||
"function or nil expected");
|
||||
if (strcmp(event, "gc") == 0)
|
||||
lua_error(L, "cannot set `gc' tag method from Lua");
|
||||
lua_gettagmethod(L, tag, event);
|
||||
lua_pushvalue(L, 3);
|
||||
lua_settagmethod(L, tag, event);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int luaB_gettagmethod (lua_State *L) {
|
||||
int tag = gettag(L, 1);
|
||||
const char *event = luaL_check_string(L, 2);
|
||||
if (strcmp(event, "gc") == 0)
|
||||
lua_error(L, "cannot get `gc' tag method from Lua");
|
||||
lua_gettagmethod(L, tag, event);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int luaB_gcinfo (lua_State *L) {
|
||||
lua_pushnumber(L, lua_getgccount(L));
|
||||
@ -262,20 +214,20 @@ static int luaB_collectgarbage (lua_State *L) {
|
||||
|
||||
static int luaB_type (lua_State *L) {
|
||||
luaL_check_any(L, 1);
|
||||
lua_pushstring(L, lua_type(L, 1));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int luaB_rawtype (lua_State *L) {
|
||||
luaL_check_any(L, 1);
|
||||
lua_pushstring(L, lua_tag2name(L, lua_rawtag(L, 1)));
|
||||
if (lua_isnull(L, 2))
|
||||
lua_pushstring(L, lua_typename(L, lua_type(L, 1)));
|
||||
else {
|
||||
if (strcmp(lua_typename(L, lua_type(L, 1)), luaL_check_string(L, 2)) == 0)
|
||||
lua_pushnumber(L, 1);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int luaB_next (lua_State *L) {
|
||||
luaL_check_rawtype(L, 1, LUA_TTABLE);
|
||||
luaL_check_type(L, 1, LUA_TTABLE);
|
||||
lua_settop(L, 2); /* create a 2nd argument if there isn't one */
|
||||
if (lua_next(L, 1))
|
||||
return 2;
|
||||
@ -393,7 +345,7 @@ static int luaB_require (lua_State *L) {
|
||||
|
||||
static int aux_unpack (lua_State *L, int arg) {
|
||||
int n, i;
|
||||
luaL_check_rawtype(L, arg, LUA_TTABLE);
|
||||
luaL_check_type(L, arg, LUA_TTABLE);
|
||||
n = lua_getn(L, arg);
|
||||
luaL_check_stack(L, n, "table too big to unpack");
|
||||
for (i=1; i<=n; i++) /* push arg[1...n] */
|
||||
@ -443,7 +395,7 @@ static int luaB_call (lua_State *L) {
|
||||
|
||||
static int luaB_tostring (lua_State *L) {
|
||||
char buff[64];
|
||||
switch (lua_rawtag(L, 1)) {
|
||||
switch (lua_type(L, 1)) {
|
||||
case LUA_TNUMBER:
|
||||
lua_pushstring(L, lua_tostring(L, 1));
|
||||
return 1;
|
||||
@ -451,16 +403,15 @@ static int luaB_tostring (lua_State *L) {
|
||||
lua_pushvalue(L, 1);
|
||||
return 1;
|
||||
case LUA_TTABLE:
|
||||
sprintf(buff, "%.40s: %p", lua_type(L, 1), lua_topointer(L, 1));
|
||||
sprintf(buff, "%.40s: %p", lua_typename(L, lua_type(L, 1)), lua_topointer(L, 1));
|
||||
break;
|
||||
case LUA_TFUNCTION:
|
||||
sprintf(buff, "function: %p", lua_topointer(L, 1));
|
||||
break;
|
||||
case LUA_TUSERDATA: {
|
||||
const char *t = lua_type(L, 1);
|
||||
const char *t = lua_typename(L, lua_type(L, 1));
|
||||
if (strcmp(t, "userdata") == 0)
|
||||
sprintf(buff, "userdata(%d): %p", lua_tag(L, 1),
|
||||
lua_touserdata(L, 1));
|
||||
sprintf(buff, "userdata: %p", lua_touserdata(L, 1));
|
||||
else
|
||||
sprintf(buff, "%.40s: %p", t, lua_touserdata(L, 1));
|
||||
break;
|
||||
@ -478,8 +429,8 @@ static int luaB_tostring (lua_State *L) {
|
||||
|
||||
static int luaB_foreachi (lua_State *L) {
|
||||
int n, i;
|
||||
luaL_check_rawtype(L, 1, LUA_TTABLE);
|
||||
luaL_check_rawtype(L, 2, LUA_TFUNCTION);
|
||||
luaL_check_type(L, 1, LUA_TTABLE);
|
||||
luaL_check_type(L, 2, LUA_TFUNCTION);
|
||||
n = lua_getn(L, 1);
|
||||
for (i=1; i<=n; i++) {
|
||||
lua_pushvalue(L, 2); /* function */
|
||||
@ -495,8 +446,8 @@ static int luaB_foreachi (lua_State *L) {
|
||||
|
||||
|
||||
static int luaB_foreach (lua_State *L) {
|
||||
luaL_check_rawtype(L, 1, LUA_TTABLE);
|
||||
luaL_check_rawtype(L, 2, LUA_TFUNCTION);
|
||||
luaL_check_type(L, 1, LUA_TTABLE);
|
||||
luaL_check_type(L, 2, LUA_TFUNCTION);
|
||||
lua_pushnil(L); /* first index */
|
||||
for (;;) {
|
||||
if (lua_next(L, 1) == 0)
|
||||
@ -523,7 +474,7 @@ static int luaB_assert (lua_State *L) {
|
||||
|
||||
|
||||
static int luaB_getn (lua_State *L) {
|
||||
luaL_check_rawtype(L, 1, LUA_TTABLE);
|
||||
luaL_check_type(L, 1, LUA_TTABLE);
|
||||
lua_pushnumber(L, lua_getn(L, 1));
|
||||
return 1;
|
||||
}
|
||||
@ -532,7 +483,7 @@ static int luaB_getn (lua_State *L) {
|
||||
static int luaB_tinsert (lua_State *L) {
|
||||
int v = lua_gettop(L); /* number of arguments */
|
||||
int n, pos;
|
||||
luaL_check_rawtype(L, 1, LUA_TTABLE);
|
||||
luaL_check_type(L, 1, LUA_TTABLE);
|
||||
n = lua_getn(L, 1);
|
||||
if (v == 2) /* called with only 2 arguments */
|
||||
pos = n+1;
|
||||
@ -553,7 +504,7 @@ static int luaB_tinsert (lua_State *L) {
|
||||
|
||||
static int luaB_tremove (lua_State *L) {
|
||||
int pos, n;
|
||||
luaL_check_rawtype(L, 1, LUA_TTABLE);
|
||||
luaL_check_type(L, 1, LUA_TTABLE);
|
||||
n = lua_getn(L, 1);
|
||||
pos = luaL_opt_int(L, 2, n);
|
||||
if (n <= 0) return 0; /* table is `empty' */
|
||||
@ -665,10 +616,10 @@ static void auxsort (lua_State *L, int l, int u) {
|
||||
|
||||
static int luaB_sort (lua_State *L) {
|
||||
int n;
|
||||
luaL_check_rawtype(L, 1, LUA_TTABLE);
|
||||
luaL_check_type(L, 1, LUA_TTABLE);
|
||||
n = lua_getn(L, 1);
|
||||
if (!lua_isnull(L, 2)) /* is there a 2nd argument? */
|
||||
luaL_check_rawtype(L, 2, LUA_TFUNCTION);
|
||||
luaL_check_type(L, 2, LUA_TFUNCTION);
|
||||
lua_settop(L, 2); /* make sure there is two arguments */
|
||||
auxsort(L, 1, n);
|
||||
return 0;
|
||||
@ -686,28 +637,19 @@ static const luaL_reg base_funcs[] = {
|
||||
{"dofile", luaB_dofile},
|
||||
{"dostring", luaB_dostring},
|
||||
{"error", luaB_error},
|
||||
{"eventtable", luaB_eventtable},
|
||||
{"foreach", luaB_foreach},
|
||||
{"foreachi", luaB_foreachi},
|
||||
{"gcinfo", luaB_gcinfo},
|
||||
{"getglobal", luaB_getglobal},
|
||||
{"gettagmethod", luaB_gettagmethod},
|
||||
{"getglobal", luaB_getglobal}, /* compatibility with 4.0 */
|
||||
{"globals", luaB_globals},
|
||||
{"loadfile", luaB_loadfile},
|
||||
{"loadstring", luaB_loadstring},
|
||||
{"newtype", luaB_newtype},
|
||||
{"newtag", luaB_newtype}, /* for compatibility 4.0 */
|
||||
{"next", luaB_next},
|
||||
{"print", luaB_print},
|
||||
{"rawget", luaB_rawget},
|
||||
{"rawset", luaB_rawset},
|
||||
{"rawgettable", luaB_rawget}, /* for compatibility 3.2 */
|
||||
{"rawsettable", luaB_rawset}, /* for compatibility 3.2 */
|
||||
{"rawtype", luaB_rawtype},
|
||||
{"setglobal", luaB_setglobal},
|
||||
{"settag", luaB_settype}, /* for compatibility 4.0 */
|
||||
{"settype", luaB_settype},
|
||||
{"settagmethod", luaB_settagmethod},
|
||||
{"tag", luaB_tag},
|
||||
{"setglobal", luaB_setglobal}, /* compatibility with 4.0 */
|
||||
{"tonumber", luaB_tonumber},
|
||||
{"tostring", luaB_tostring},
|
||||
{"type", luaB_type},
|
||||
|
29
ldebug.c
29
ldebug.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ldebug.c,v 1.92 2001/10/31 19:58:11 roberto Exp $
|
||||
** $Id: ldebug.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
|
||||
** Debug Interface
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -205,22 +205,8 @@ static void funcinfo (lua_State *L, lua_Debug *ar, StkId func) {
|
||||
}
|
||||
|
||||
|
||||
static const char *travtagmethods (global_State *G, const TObject *o) {
|
||||
if (ttype(o) == LUA_TFUNCTION) {
|
||||
int e;
|
||||
for (e=0; e<TM_N; e++) {
|
||||
int t;
|
||||
for (t=0; t<G->ntag; t++)
|
||||
if (clvalue(o) == luaT_gettm(G, t, e))
|
||||
return luaT_eventname[e];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static const char *travglobals (lua_State *L, const TObject *o) {
|
||||
Table *g = hvalue(&L->gt);
|
||||
Table *g = hvalue(gt(L));
|
||||
int i = sizenode(g);
|
||||
while (i--) {
|
||||
Node *n = node(g, i);
|
||||
@ -235,10 +221,7 @@ static void getname (lua_State *L, const TObject *f, lua_Debug *ar) {
|
||||
/* try to find a name for given function */
|
||||
if ((ar->name = travglobals(L, f)) != NULL)
|
||||
ar->namewhat = "global";
|
||||
/* not found: try tag methods */
|
||||
else if ((ar->name = travtagmethods(G(L), f)) != NULL)
|
||||
ar->namewhat = "tag-method";
|
||||
else ar->namewhat = ""; /* not found at all */
|
||||
else ar->namewhat = ""; /* not found */
|
||||
}
|
||||
|
||||
|
||||
@ -531,7 +514,7 @@ static const char *getfuncname (lua_State *L, CallInfo *ci,
|
||||
void luaG_typeerror (lua_State *L, StkId o, const char *op) {
|
||||
const char *name;
|
||||
const char *kind = getobjname(L, o, &name);
|
||||
const char *t = luaT_typename(G(L), o);
|
||||
const char *t = luaT_typenames[ttype(o)];
|
||||
if (kind)
|
||||
luaO_verror(L, "attempt to %.30s %.20s `%.40s' (a %.10s value)",
|
||||
op, kind, name, t);
|
||||
@ -556,8 +539,8 @@ void luaG_aritherror (lua_State *L, StkId p1, TObject *p2) {
|
||||
|
||||
|
||||
void luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2) {
|
||||
const char *t1 = luaT_typename(G(L), p1);
|
||||
const char *t2 = luaT_typename(G(L), p2);
|
||||
const char *t1 = luaT_typenames[ttype(p1)];
|
||||
const char *t2 = luaT_typenames[ttype(p2)];
|
||||
if (t1[2] == t2[2])
|
||||
luaO_verror(L, "attempt to compare two %.10s values", t1);
|
||||
else
|
||||
|
21
ldo.c
21
ldo.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ldo.c,v 1.144 2001/11/27 20:56:47 roberto Exp $
|
||||
** $Id: ldo.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
|
||||
** Stack and Call structure of Lua
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -43,8 +43,7 @@ void luaD_init (lua_State *L, int stacksize) {
|
||||
stacksize += EXTRA_STACK;
|
||||
L->stack = luaM_newvector(L, stacksize, TObject);
|
||||
L->stacksize = stacksize;
|
||||
setnilvalue(L->stack); /* the `initial' function */
|
||||
L->top = L->basefunc.base = L->stack + 1;
|
||||
L->top = L->basefunc.base = L->stack + RESERVED_STACK_PREFIX;
|
||||
restore_stack_limit(L);
|
||||
}
|
||||
|
||||
@ -143,12 +142,13 @@ void luaD_call (lua_State *L, StkId func) {
|
||||
CallInfo ci;
|
||||
if (ttype(func) != LUA_TFUNCTION) {
|
||||
/* `func' is not a function; check the `function' tag method */
|
||||
Closure *tm = luaT_gettmbyObj(G(L), func, TM_FUNCTION);
|
||||
if (tm == NULL)
|
||||
const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL);
|
||||
if (tm == NULL || ttype(tm) != LUA_TFUNCTION)
|
||||
luaG_typeerror(L, func, "call");
|
||||
luaD_openstack(L, func);
|
||||
setclvalue(func, tm); /* tag method is the new function to be called */
|
||||
setobj(func, tm); /* tag method is the new function to be called */
|
||||
}
|
||||
lua_assert(ttype(func) == LUA_TFUNCTION);
|
||||
ci.prev = L->ci; /* chain new callinfo */
|
||||
L->ci = &ci;
|
||||
ci.base = func+1;
|
||||
@ -300,9 +300,12 @@ struct lua_longjmp {
|
||||
|
||||
|
||||
static void message (lua_State *L, const char *s) {
|
||||
StkId top = L->top;
|
||||
luaV_getglobal(L, luaS_newliteral(L, LUA_ERRORMESSAGE), top);
|
||||
if (ttype(top) == LUA_TFUNCTION) {
|
||||
TObject o, m;
|
||||
setsvalue(&o, luaS_newliteral(L, LUA_ERRORMESSAGE));
|
||||
luaV_gettable(L, gt(L), &o, &m);
|
||||
if (ttype(&m) == LUA_TFUNCTION) {
|
||||
StkId top = L->top;
|
||||
setobj(top, &m);
|
||||
incr_top;
|
||||
setsvalue(top+1, luaS_new(L, s));
|
||||
incr_top;
|
||||
|
4
lfunc.c
4
lfunc.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lfunc.c,v 1.49 2001/11/06 21:41:53 roberto Exp $
|
||||
** $Id: lfunc.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
|
||||
** Auxiliary functions to manipulate prototypes and closures
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -54,7 +54,6 @@ UpVal *luaF_findupval (lua_State *L, StkId level) {
|
||||
}
|
||||
p = luaM_new(L, UpVal); /* not found: create a new one */
|
||||
p->v = level; /* current value lives in the stack */
|
||||
p->mark = 1; /* won't participate in GC while open */
|
||||
p->next = *pp; /* chain it in the proper position */
|
||||
*pp = p;
|
||||
return p;
|
||||
@ -68,7 +67,6 @@ void luaF_close (lua_State *L, StkId level) {
|
||||
p->v = &p->value; /* now current value lives here */
|
||||
L->openupval = p->next; /* remove from `open' list */
|
||||
p->next = G(L)->rootupval; /* chain in `closed' list */
|
||||
p->mark = 0; /* now it can be collected */
|
||||
G(L)->rootupval = p;
|
||||
}
|
||||
}
|
||||
|
121
lgc.c
121
lgc.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lgc.c,v 1.116 2001/11/06 21:41:53 roberto Exp $
|
||||
** $Id: lgc.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
|
||||
** Garbage Collector
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -30,6 +30,15 @@ typedef struct GCState {
|
||||
#define strmark(s) {if ((s)->tsv.marked == 0) (s)->tsv.marked = 1;}
|
||||
|
||||
|
||||
/* mark tricks for userdata */
|
||||
#define isudmarked(u) (u->uv.len & 1)
|
||||
#define markud(u) (u->uv.len |= 1)
|
||||
#define unmarkud(u) (u->uv.len--)
|
||||
|
||||
|
||||
/* mark tricks for upvalues (assume that open upvalues are always marked) */
|
||||
#define isupvalmarked(uv) ((uv)->v != &(uv)->value)
|
||||
|
||||
|
||||
static void markobject (GCState *st, TObject *o);
|
||||
|
||||
@ -66,9 +75,9 @@ static void markclosure (GCState *st, Closure *cl) {
|
||||
protomark(cl->l.p);
|
||||
for (i=0; i<cl->l.nupvalues; i++) { /* mark its upvalues */
|
||||
UpVal *u = cl->l.upvals[i];
|
||||
if (!u->mark) {
|
||||
u->mark = 1;
|
||||
markobject(st, u->v);
|
||||
if (!isupvalmarked(u)) {
|
||||
markobject(st, &u->value);
|
||||
u->v = NULL; /* mark it! */
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -90,8 +99,8 @@ static void markobject (GCState *st, TObject *o) {
|
||||
strmark(tsvalue(o));
|
||||
break;
|
||||
case LUA_TUSERDATA:
|
||||
if (!ismarkedudata(uvalue(o)))
|
||||
switchudatamark(uvalue(o));
|
||||
if (!isudmarked(uvalue(o)))
|
||||
markud(uvalue(o));
|
||||
break;
|
||||
case LUA_TFUNCTION:
|
||||
markclosure(st, clvalue(o));
|
||||
@ -112,7 +121,6 @@ static void markstacks (lua_State *L, GCState *st) {
|
||||
lua_State *L1 = L;
|
||||
do { /* for each thread */
|
||||
StkId o, lim;
|
||||
markobject(st, &L1->gt); /* mark table of globals */
|
||||
for (o=L1->stack; o<L1->top; o++)
|
||||
markobject(st, o);
|
||||
lim = (L1->stack_last - L1->ci->base > MAXSTACK) ? L1->ci->base+MAXSTACK
|
||||
@ -124,17 +132,10 @@ static void markstacks (lua_State *L, GCState *st) {
|
||||
}
|
||||
|
||||
|
||||
static void marktagmethods (global_State *G, GCState *st) {
|
||||
int t;
|
||||
for (t=0; t<G->ntag; t++) {
|
||||
struct TM *tm = &G->TMtable[t];
|
||||
int e;
|
||||
if (tm->name) strmark(tm->name);
|
||||
for (e=0; e<TM_N; e++) {
|
||||
Closure *cl = tm->method[e];
|
||||
if (cl) markclosure(st, cl);
|
||||
}
|
||||
}
|
||||
static void markudet (lua_State *L, GCState *st) {
|
||||
Udata *u;
|
||||
for (u = G(L)->rootudata; u; u = u->uv.next)
|
||||
marktable(st, u->uv.eventtable);
|
||||
}
|
||||
|
||||
|
||||
@ -152,6 +153,7 @@ static void traversetable (GCState *st, Table *h) {
|
||||
h->mark = st->toclear; /* put in the appropriate list */
|
||||
st->toclear = h;
|
||||
}
|
||||
marktable(st, h->eventtable);
|
||||
if (!(mode & LUA_WEAK_VALUE)) {
|
||||
i = sizearray(h);
|
||||
while (i--)
|
||||
@ -172,11 +174,9 @@ static void traversetable (GCState *st, Table *h) {
|
||||
|
||||
|
||||
static void markall (lua_State *L, GCState *st) {
|
||||
marktagmethods(G(L), st); /* mark tag methods */
|
||||
markstacks(L, st); /* mark all stacks */
|
||||
marktable(st, G(L)->type2tag);
|
||||
markobject(st, &G(L)->registry);
|
||||
while (st->tmark) { /* mark tables */
|
||||
markudet(L, st); /* mark userdata's event tables */
|
||||
while (st->tmark) { /* traverse marked tables */
|
||||
Table *h = st->tmark; /* get first table from list */
|
||||
st->tmark = h->mark; /* remove it from list */
|
||||
traversetable(st, h);
|
||||
@ -189,7 +189,7 @@ static int hasmark (const TObject *o) {
|
||||
case LUA_TSTRING:
|
||||
return tsvalue(o)->tsv.marked;
|
||||
case LUA_TUSERDATA:
|
||||
return ismarkedudata(uvalue(o));
|
||||
return isudmarked(uvalue(o));
|
||||
case LUA_TTABLE:
|
||||
return ismarked(hvalue(o));
|
||||
case LUA_TFUNCTION:
|
||||
@ -261,8 +261,9 @@ static void collectupval (lua_State *L) {
|
||||
UpVal **v = &G(L)->rootupval;
|
||||
UpVal *curr;
|
||||
while ((curr = *v) != NULL) {
|
||||
if (curr->mark) {
|
||||
curr->mark = 0;
|
||||
if (isupvalmarked(curr)) {
|
||||
lua_assert(curr->v == NULL);
|
||||
curr->v = &curr->value; /* unmark */
|
||||
v = &curr->next; /* next */
|
||||
}
|
||||
else {
|
||||
@ -289,26 +290,27 @@ static void collecttable (lua_State *L) {
|
||||
}
|
||||
|
||||
|
||||
static void collectudata (lua_State *L, int keep) {
|
||||
static Udata *collectudata (lua_State *L, int keep) {
|
||||
Udata **p = &G(L)->rootudata;
|
||||
Udata *curr;
|
||||
Udata *collected = NULL;
|
||||
while ((curr = *p) != NULL) {
|
||||
if (ismarkedudata(curr)) {
|
||||
switchudatamark(curr); /* unmark */
|
||||
if (isudmarked(curr)) {
|
||||
unmarkud(curr);
|
||||
p = &curr->uv.next;
|
||||
}
|
||||
else { /* collect */
|
||||
int tag = curr->uv.tag;
|
||||
const TObject *tm = fasttm(L, curr->uv.eventtable, TM_GC);
|
||||
*p = curr->uv.next;
|
||||
if (keep || /* must keep all of them (to close state)? */
|
||||
luaT_gettm(G(L), tag, TM_GC)) { /* or is there a GC tag method? */
|
||||
curr->uv.next = G(L)->TMtable[tag].collected; /* chain udata ... */
|
||||
G(L)->TMtable[tag].collected = curr; /* ... to call its TM later */
|
||||
if (keep || tm != NULL) {
|
||||
curr->uv.next = collected;
|
||||
collected = curr;
|
||||
}
|
||||
else /* no tag method; delete udata */
|
||||
else /* no gc action; delete udata */
|
||||
luaM_free(L, curr, sizeudata(curr->uv.len));
|
||||
}
|
||||
}
|
||||
return collected;
|
||||
}
|
||||
|
||||
|
||||
@ -347,14 +349,14 @@ static void checkMbuffer (lua_State *L) {
|
||||
}
|
||||
|
||||
|
||||
static void callgcTM (lua_State *L, const TObject *obj) {
|
||||
Closure *tm = luaT_gettmbyObj(G(L), obj, TM_GC);
|
||||
if (tm != NULL) {
|
||||
static void callgcTM (lua_State *L, Udata *udata) {
|
||||
const TObject *tm = fasttm(L, udata->uv.eventtable, TM_GC);
|
||||
if (tm != NULL && ttype(tm) == LUA_TFUNCTION) {
|
||||
int oldah = L->allowhooks;
|
||||
StkId top = L->top;
|
||||
L->allowhooks = 0; /* stop debug hooks during GC tag methods */
|
||||
setclvalue(top, tm);
|
||||
setobj(top+1, obj);
|
||||
setobj(top, tm);
|
||||
setuvalue(top+1, udata);
|
||||
L->top += 2;
|
||||
luaD_call(L, top);
|
||||
L->top = top; /* restore top */
|
||||
@ -363,53 +365,52 @@ static void callgcTM (lua_State *L, const TObject *obj) {
|
||||
}
|
||||
|
||||
|
||||
static void callgcTMudata (lua_State *L) {
|
||||
int tag;
|
||||
static void callgcTMudata (lua_State *L, Udata *c) {
|
||||
luaD_checkstack(L, 3);
|
||||
for (tag=G(L)->ntag-1; tag>=0; tag--) { /* for each tag (in reverse order) */
|
||||
Udata *udata;
|
||||
while ((udata = G(L)->TMtable[tag].collected) != NULL) {
|
||||
G(L)->TMtable[tag].collected = udata->uv.next; /* remove it from list */
|
||||
udata->uv.next = G(L)->rootudata; /* resurect it */
|
||||
G(L)->rootudata = udata;
|
||||
setuvalue(L->top, udata);
|
||||
L->top++; /* keep it in stack to avoid being (recursively) collected */
|
||||
callgcTM(L, L->top-1);
|
||||
uvalue(L->top-1)->uv.tag = 0; /* default tag (udata is `finalized') */
|
||||
L->top--;
|
||||
}
|
||||
L->top++; /* reserve space to keep udata while runs its gc method */
|
||||
while (c != NULL) {
|
||||
Udata *udata = c;
|
||||
c = udata->uv.next; /* remove udata from list */
|
||||
udata->uv.next = G(L)->rootudata; /* resurect it */
|
||||
G(L)->rootudata = udata;
|
||||
setuvalue(L->top - 1, udata);
|
||||
callgcTM(L, udata);
|
||||
/* mark udata as finalized (default event table) */
|
||||
uvalue(L->top-1)->uv.eventtable = hvalue(defaultet(L));
|
||||
}
|
||||
L->top--;
|
||||
}
|
||||
|
||||
|
||||
void luaC_callallgcTM (lua_State *L) {
|
||||
if (G(L)->rootudata) { /* avoid problems with incomplete states */
|
||||
collectudata(L, 1); /* collect all udata into tag lists */
|
||||
callgcTMudata(L); /* call their GC tag methods */
|
||||
Udata *c = collectudata(L, 1); /* collect all udata */
|
||||
callgcTMudata(L, c); /* call their GC tag methods */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void luaC_collect (lua_State *L, int all) {
|
||||
collectudata(L, 0);
|
||||
Udata *luaC_collect (lua_State *L, int all) {
|
||||
Udata *c = collectudata(L, 0);
|
||||
collectstrings(L, all);
|
||||
collecttable(L);
|
||||
collectproto(L);
|
||||
collectupval(L);
|
||||
collectclosures(L);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
void luaC_collectgarbage (lua_State *L) {
|
||||
Udata *c;
|
||||
GCState st;
|
||||
st.tmark = NULL;
|
||||
st.toclear = NULL;
|
||||
markall(L, &st);
|
||||
cleartables(st.toclear);
|
||||
luaC_collect(L, 0);
|
||||
c = luaC_collect(L, 0);
|
||||
checkMbuffer(L);
|
||||
G(L)->GCthreshold = 2*G(L)->nblocks; /* new threshold */
|
||||
callgcTMudata(L);
|
||||
callgcTM(L, &luaO_nilobject);
|
||||
callgcTMudata(L, c);
|
||||
}
|
||||
|
||||
|
4
lgc.h
4
lgc.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lgc.h,v 1.11 2001/06/12 18:43:13 roberto Exp roberto $
|
||||
** $Id: lgc.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
|
||||
** Garbage Collector
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -16,7 +16,7 @@
|
||||
|
||||
|
||||
void luaC_callallgcTM (lua_State *L);
|
||||
void luaC_collect (lua_State *L, int all);
|
||||
Udata *luaC_collect (lua_State *L, int all);
|
||||
void luaC_collectgarbage (lua_State *L);
|
||||
|
||||
|
||||
|
58
liolib.c
58
liolib.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: liolib.c,v 1.124 2001/10/26 17:33:30 roberto Exp $
|
||||
** $Id: liolib.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
|
||||
** Standard I/O (and system) library
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -61,6 +61,7 @@ static int pushresult (lua_State *L, int i) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** FILE Operations
|
||||
@ -68,14 +69,30 @@ static int pushresult (lua_State *L, int i) {
|
||||
*/
|
||||
|
||||
|
||||
#define checkfile(L,f) (strcmp(lua_type(L,(f)), FILEHANDLE) == 0)
|
||||
|
||||
static int checkfile (lua_State *L, int findex, const char *tname) {
|
||||
int res;
|
||||
lua_geteventtable(L, findex);
|
||||
lua_pushstring(L, tname);
|
||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||
res = lua_equal(L, -1, -2);
|
||||
lua_pop(L, 2);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/* temporary?? should be in auxlib... */
|
||||
static void *luaL_check_userdata (lua_State *L, int findex, const char *tn) {
|
||||
luaL_arg_check(L, checkfile(L, findex, tn), findex, "bad file");
|
||||
return lua_touserdata(L, findex);
|
||||
}
|
||||
|
||||
|
||||
static FILE *getopthandle (lua_State *L, int inout) {
|
||||
FILE *p = (FILE *)(lua_touserdata(L, 1));
|
||||
if (p != NULL) { /* is it a userdata ? */
|
||||
if (!checkfile(L, 1)) { /* not a valid file handle? */
|
||||
if (strcmp(lua_type(L, 1), CLOSEDFILEHANDLE) == 0)
|
||||
if (!checkfile(L, 1, FILEHANDLE)) { /* not a valid file handle? */
|
||||
if (checkfile(L, 1, CLOSEDFILEHANDLE))
|
||||
luaL_argerror(L, 1, "file is closed");
|
||||
else
|
||||
luaL_argerror(L, 1, "(invalid value)");
|
||||
@ -84,7 +101,7 @@ static FILE *getopthandle (lua_State *L, int inout) {
|
||||
}
|
||||
else { /* try global value */
|
||||
lua_getglobal(L, filenames[inout]);
|
||||
if (!checkfile(L,-1))
|
||||
if (!checkfile(L, -1, FILEHANDLE))
|
||||
luaL_verror(L, "global variable `%.10s' is not a valid file handle",
|
||||
filenames[inout]);
|
||||
p = (FILE *)(lua_touserdata(L, -1));
|
||||
@ -95,7 +112,9 @@ static FILE *getopthandle (lua_State *L, int inout) {
|
||||
|
||||
static void newfile (lua_State *L, FILE *f) {
|
||||
lua_newuserdatabox(L, f);
|
||||
lua_settag(L, lua_name2tag(L, FILEHANDLE));
|
||||
lua_pushliteral(L, FILEHANDLE);
|
||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||
lua_seteventtable(L, -2);
|
||||
}
|
||||
|
||||
|
||||
@ -130,7 +149,9 @@ static int io_close (lua_State *L) {
|
||||
int status = 1;
|
||||
if (f != stdin && f != stdout && f != stderr) {
|
||||
lua_settop(L, 1); /* make sure file is on top */
|
||||
lua_settag(L, lua_name2tag(L, CLOSEDFILEHANDLE));
|
||||
lua_pushliteral(L, CLOSEDFILEHANDLE);
|
||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||
lua_seteventtable(L, 1);
|
||||
status = (CLOSEFILE(L, f) == 0);
|
||||
}
|
||||
return pushresult(L, status);
|
||||
@ -301,7 +322,7 @@ static int io_read (lua_State *L) {
|
||||
luaL_check_stack(L, nargs+LUA_MINSTACK, "too many arguments");
|
||||
success = 1;
|
||||
for (n = 1; n<=nargs && success; n++) {
|
||||
if (lua_rawtag(L, n) == LUA_TNUMBER) {
|
||||
if (lua_type(L, n) == LUA_TNUMBER) {
|
||||
size_t l = (size_t)lua_tonumber(L, n);
|
||||
success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l);
|
||||
}
|
||||
@ -353,7 +374,7 @@ static int io_write (lua_State *L) {
|
||||
int arg;
|
||||
int status = 1;
|
||||
for (arg=1; arg<=nargs; arg++) {
|
||||
if (lua_rawtag(L, arg) == LUA_TNUMBER) {
|
||||
if (lua_type(L, arg) == LUA_TNUMBER) {
|
||||
/* optimization: could be done exactly as for strings */
|
||||
status = status &&
|
||||
fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
|
||||
@ -514,7 +535,7 @@ static int io_time (lua_State *L) {
|
||||
else {
|
||||
time_t t;
|
||||
struct tm ts;
|
||||
luaL_check_rawtype(L, 1, LUA_TTABLE);
|
||||
luaL_check_type(L, 1, LUA_TTABLE);
|
||||
lua_settop(L, 1); /* make sure table is at the top */
|
||||
ts.tm_sec = getfield(L, "sec", 0);
|
||||
ts.tm_min = getfield(L, "min", 0);
|
||||
@ -677,8 +698,18 @@ static const luaL_reg iolib[] = {
|
||||
|
||||
|
||||
LUALIB_API int lua_iolibopen (lua_State *L) {
|
||||
int iotag = lua_newtype(L, FILEHANDLE, LUA_TUSERDATA);
|
||||
lua_newtype(L, CLOSEDFILEHANDLE, LUA_TUSERDATA);
|
||||
lua_pushliteral(L, FILEHANDLE);
|
||||
lua_newtable(L); /* event table for FILEHANDLE */
|
||||
/* close files when collected */
|
||||
lua_pushliteral(L, "gc");
|
||||
lua_pushcfunction(L, file_collect);
|
||||
lua_settable(L, -3);
|
||||
/* put new eventtable into registry */
|
||||
lua_settable(L, LUA_REGISTRYINDEX); /* registry.FILEHANDLE = eventtable */
|
||||
lua_pushliteral(L, CLOSEDFILEHANDLE);
|
||||
/* event table for CLOSEDFILEHANDLE */
|
||||
lua_newtable(L);
|
||||
lua_settable(L, LUA_REGISTRYINDEX);
|
||||
luaL_openl(L, iolib);
|
||||
/* predefined file handles */
|
||||
newfilewithname(L, stdin, basicfiles[INFILE]);
|
||||
@ -686,9 +717,6 @@ LUALIB_API int lua_iolibopen (lua_State *L) {
|
||||
newfilewithname(L, stderr, "_STDERR");
|
||||
resetfile(L, INFILE);
|
||||
resetfile(L, OUTFILE);
|
||||
/* close files when collected */
|
||||
lua_pushcfunction(L, file_collect);
|
||||
lua_settagmethod(L, iotag, "gc");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lmathlib.c,v 1.38 2001/03/26 14:31:49 roberto Exp $
|
||||
** $Id: lmathlib.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
|
||||
** Standard mathematical library
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -220,6 +220,7 @@ static const luaL_reg mathlib[] = {
|
||||
{"log10", math_log10},
|
||||
{"exp", math_exp},
|
||||
{"deg", math_deg},
|
||||
{"pow", math_pow},
|
||||
{"rad", math_rad},
|
||||
{"random", math_random},
|
||||
{"randomseed", math_randomseed}
|
||||
@ -230,8 +231,6 @@ static const luaL_reg mathlib[] = {
|
||||
*/
|
||||
LUALIB_API int lua_mathlibopen (lua_State *L) {
|
||||
luaL_openl(L, mathlib);
|
||||
lua_pushcfunction(L, math_pow);
|
||||
lua_settagmethod(L, LUA_TNUMBER, "pow");
|
||||
lua_pushnumber(L, PI);
|
||||
lua_setglobal(L, "PI");
|
||||
return 0;
|
||||
|
22
lobject.h
22
lobject.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lobject.h,v 1.116 2001/11/06 21:41:53 roberto Exp $
|
||||
** $Id: lobject.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
|
||||
** Type definitions for Lua objects
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -31,15 +31,6 @@
|
||||
#define NUM_TAGS 6
|
||||
|
||||
|
||||
/*
|
||||
** extra tags:
|
||||
** first is used locally when moving an upvalue from the stack to the heap;
|
||||
** second prefixes upvalues in the heap
|
||||
*/
|
||||
#define LUA_TUPVAL 6
|
||||
#define LUA_HEAPUPVAL 7
|
||||
|
||||
|
||||
typedef union {
|
||||
union TString *ts;
|
||||
union Udata *u;
|
||||
@ -122,17 +113,14 @@ typedef union TString {
|
||||
typedef union Udata {
|
||||
union L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
|
||||
struct {
|
||||
int tag; /* negative means `marked' (only during GC) */
|
||||
struct Table *eventtable;
|
||||
void *value;
|
||||
size_t len;
|
||||
size_t len; /* least bit reserved for gc mark */
|
||||
union Udata *next; /* chain for list of all udata */
|
||||
} uv;
|
||||
} Udata;
|
||||
|
||||
|
||||
#define switchudatamark(u) ((u)->uv.tag = (-((u)->uv.tag+1)))
|
||||
#define ismarkedudata(u) ((u)->uv.tag < 0)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
@ -175,7 +163,6 @@ typedef struct LocVar {
|
||||
|
||||
typedef struct UpVal {
|
||||
TObject *v; /* points to stack or to its own value */
|
||||
int mark;
|
||||
struct UpVal *next;
|
||||
TObject value; /* the value (when closed) */
|
||||
} UpVal;
|
||||
@ -227,12 +214,13 @@ typedef struct Node {
|
||||
|
||||
|
||||
typedef struct Table {
|
||||
struct Table *eventtable;
|
||||
TObject *array; /* array part */
|
||||
Node *node;
|
||||
int htag;
|
||||
int sizearray; /* size of `array' array */
|
||||
lu_byte lsizenode; /* log2 of size of `node' array */
|
||||
lu_byte weakmode;
|
||||
unsigned short flags; /* 1<<p means tagmethod(p) is not present */
|
||||
Node *firstfree; /* this position is free; all positions after it are full */
|
||||
struct Table *next;
|
||||
struct Table *mark; /* marked tables (point to itself when not marked) */
|
||||
|
21
lstate.c
21
lstate.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lstate.c,v 1.72 2001/11/06 21:40:51 roberto Exp $
|
||||
** $Id: lstate.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
|
||||
** Global State
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -40,12 +40,14 @@ static void f_luaopen (lua_State *L, void *ud) {
|
||||
so->stacksize += LUA_MINSTACK;
|
||||
if (so->L != NULL) { /* shared global state? */
|
||||
L->_G = G(so->L);
|
||||
L->gt = so->L->gt; /* share table of globals */
|
||||
so->L->next->previous = L; /* insert L into linked list */
|
||||
L->next = so->L->next;
|
||||
so->L->next = L;
|
||||
L->previous = so->L;
|
||||
luaD_init(L, so->stacksize); /* init stack */
|
||||
setobj(defaultet(L), defaultet(so->L)); /* share default event table */
|
||||
setobj(gt(L), gt(so->L)); /* share table of globals */
|
||||
setobj(registry(L), registry(so->L)); /* share registry */
|
||||
}
|
||||
else { /* create a new global state */
|
||||
L->_G = luaM_new(L, global_State);
|
||||
@ -59,17 +61,17 @@ static void f_luaopen (lua_State *L, void *ud) {
|
||||
G(L)->roottable = NULL;
|
||||
G(L)->rootudata = NULL;
|
||||
G(L)->rootupval = NULL;
|
||||
G(L)->TMtable = NULL;
|
||||
G(L)->sizeTM = 0;
|
||||
G(L)->ntag = 0;
|
||||
G(L)->nblocks = sizeof(lua_State) + sizeof(global_State);
|
||||
luaD_init(L, so->stacksize); /* init stack */
|
||||
sethvalue(&L->gt, luaH_new(L, 0, 4)); /* table of globals */
|
||||
G(L)->type2tag = luaH_new(L, 0, 3);
|
||||
sethvalue(&G(L)->registry, luaH_new(L, 0, 0));
|
||||
/* create default event table with a dummy table, and then close the loop */
|
||||
sethvalue(defaultet(L), NULL);
|
||||
sethvalue(defaultet(L), luaH_new(L, 0, 4));
|
||||
hvalue(defaultet(L))->eventtable = hvalue(defaultet(L));
|
||||
sethvalue(gt(L), luaH_new(L, 0, 4)); /* table of globals */
|
||||
sethvalue(registry(L), luaH_new(L, 0, 0)); /* registry */
|
||||
luaS_resize(L, 4); /* initial size of string table */
|
||||
luaX_init(L);
|
||||
luaT_init(L);
|
||||
luaX_init(L);
|
||||
G(L)->GCthreshold = 4*G(L)->nblocks;
|
||||
}
|
||||
}
|
||||
@ -122,7 +124,6 @@ static void close_state (lua_State *L, lua_State *OL) {
|
||||
lua_assert(G(L)->rootupval == NULL);
|
||||
lua_assert(G(L)->roottable == NULL);
|
||||
luaS_freeall(L);
|
||||
luaM_freearray(L, G(L)->TMtable, G(L)->sizeTM, struct TM);
|
||||
luaM_freearray(L, G(L)->Mbuffer, G(L)->Mbuffsize, char);
|
||||
luaM_freelem(NULL, L->_G);
|
||||
}
|
||||
|
34
lstate.h
34
lstate.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lstate.h,v 1.64 2001/11/06 21:40:51 roberto Exp $
|
||||
** $Id: lstate.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
|
||||
** Global State
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -7,8 +7,10 @@
|
||||
#ifndef lstate_h
|
||||
#define lstate_h
|
||||
|
||||
#include "lobject.h"
|
||||
#include "lua.h"
|
||||
|
||||
#include "lobject.h"
|
||||
#include "ltm.h"
|
||||
#include "luadebug.h"
|
||||
|
||||
|
||||
@ -40,7 +42,24 @@
|
||||
|
||||
|
||||
struct lua_longjmp; /* defined in ldo.c */
|
||||
struct TM; /* defined in ltm.h */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** reserve init of stack to store some global values
|
||||
*/
|
||||
|
||||
/* default event table (both for tables and udata) */
|
||||
#define defaultet(L) (L->stack)
|
||||
|
||||
/* table of globals */
|
||||
#define gt(L) (L->stack + 1)
|
||||
|
||||
/* registry */
|
||||
#define registry(L) (L->stack + 2)
|
||||
|
||||
#define RESERVED_STACK_PREFIX 3
|
||||
|
||||
|
||||
|
||||
typedef struct stringtable {
|
||||
@ -57,11 +76,6 @@ typedef struct global_State {
|
||||
void *Mbuffer; /* global buffer */
|
||||
size_t Mbuffsize; /* size of Mbuffer */
|
||||
stringtable strt; /* hash table for strings */
|
||||
Table *type2tag; /* hash table from type names to tags */
|
||||
TObject registry; /* registry table */
|
||||
struct TM *TMtable; /* table for tag methods */
|
||||
int sizeTM; /* size of TMtable */
|
||||
int ntag; /* number of tags in TMtable */
|
||||
lu_mem GCthreshold;
|
||||
lu_mem nblocks; /* number of `bytes' currently allocated */
|
||||
Proto *rootproto; /* list of all prototypes */
|
||||
@ -69,6 +83,7 @@ typedef struct global_State {
|
||||
Table *roottable; /* list of all tables */
|
||||
Udata *rootudata; /* list of all userdata */
|
||||
UpVal *rootupval; /* list of closed up values */
|
||||
TString *tmname[TM_N]; /* array with tag-method names */
|
||||
} global_State;
|
||||
|
||||
|
||||
@ -80,10 +95,9 @@ struct lua_State {
|
||||
StkId top; /* first free slot in the stack */
|
||||
CallInfo *ci; /* call info for current function */
|
||||
StkId stack_last; /* last free slot in the stack */
|
||||
TObject gt; /* table for globals */
|
||||
global_State *_G;
|
||||
StkId stack; /* stack base */
|
||||
int stacksize;
|
||||
global_State *_G;
|
||||
lua_Hook callhook;
|
||||
lua_Hook linehook;
|
||||
int allowhooks;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lstring.c,v 1.67 2001/08/31 19:46:07 roberto Exp $
|
||||
** $Id: lstring.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
|
||||
** String table (keeps all strings handled by Lua)
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -84,9 +84,11 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
|
||||
|
||||
|
||||
Udata *luaS_newudata (lua_State *L, size_t s) {
|
||||
Udata *u = cast(Udata *, luaM_malloc(L, sizeudata(s)));
|
||||
Udata *u;
|
||||
if (s & 1) s++; /* make sure size is even */
|
||||
u = cast(Udata *, luaM_malloc(L, sizeudata(s)));
|
||||
u->uv.len = s;
|
||||
u->uv.tag = 0;
|
||||
u->uv.eventtable = hvalue(defaultet(L));
|
||||
u->uv.value = u + 1;
|
||||
/* chain it on udata list */
|
||||
u->uv.next = G(L)->rootudata;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lstrlib.c,v 1.73 2001/10/26 17:33:30 roberto Exp $
|
||||
** $Id: lstrlib.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
|
||||
** Standard library for string operations and pattern-matching
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -97,7 +97,7 @@ static int str_concat (lua_State *L) {
|
||||
size_t lsep;
|
||||
const char *sep = luaL_opt_lstr(L, 2, "", &lsep);
|
||||
int n, i;
|
||||
luaL_check_rawtype(L, 1, LUA_TTABLE);
|
||||
luaL_check_type(L, 1, LUA_TTABLE);
|
||||
luaL_buffinit(L, &b);
|
||||
n = lua_getn(L, 1);
|
||||
for (i=1; i<=n; i++) {
|
||||
|
19
ltable.c
19
ltable.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ltable.c,v 1.88 2001/11/16 16:29:51 roberto Exp $
|
||||
** $Id: ltable.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
|
||||
** Lua tables (hash)
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -258,11 +258,12 @@ static void rehash (lua_State *L, Table *t) {
|
||||
|
||||
Table *luaH_new (lua_State *L, int narray, int lnhash) {
|
||||
Table *t = luaM_new(L, Table);
|
||||
t->htag = TagDefault;
|
||||
t->eventtable = hvalue(defaultet(L));
|
||||
t->next = G(L)->roottable;
|
||||
G(L)->roottable = t;
|
||||
t->mark = t;
|
||||
t->weakmode = 0;
|
||||
t->flags = ~0;
|
||||
/* temporary values (kept only if some malloc fails) */
|
||||
t->array = NULL;
|
||||
t->sizearray = 0;
|
||||
@ -419,19 +420,7 @@ void luaH_set (lua_State *L, Table *t, const TObject *key, const TObject *val) {
|
||||
if (ttype(key) == LUA_TNIL) luaD_error(L, "table index is nil");
|
||||
newkey(L, t, key, val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void luaH_setstr (lua_State *L, Table *t, TString *key, const TObject *val) {
|
||||
const TObject *p = luaH_getstr(t, key);
|
||||
if (p != &luaO_nilobject) {
|
||||
settableval(p, val);
|
||||
}
|
||||
else {
|
||||
TObject k;
|
||||
setsvalue(&k, key);
|
||||
newkey(L, t, &k, val);
|
||||
}
|
||||
t->flags = 0;
|
||||
}
|
||||
|
||||
|
||||
|
3
ltable.h
3
ltable.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ltable.h,v 1.37 2001/10/25 19:14:14 roberto Exp $
|
||||
** $Id: ltable.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
|
||||
** Lua tables (hash)
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -20,7 +20,6 @@
|
||||
const TObject *luaH_getnum (Table *t, int key);
|
||||
void luaH_setnum (lua_State *L, Table *t, int key, const TObject *val);
|
||||
const TObject *luaH_getstr (Table *t, TString *key);
|
||||
void luaH_setstr (lua_State *L, Table *t, TString *key, const TObject *val);
|
||||
const TObject *luaH_get (Table *t, const TObject *key);
|
||||
void luaH_set (lua_State *L, Table *t, const TObject *key, const TObject *val);
|
||||
Table *luaH_new (lua_State *L, int narray, int lnhash);
|
||||
|
61
ltests.c
61
ltests.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ltests.c,v 1.96 2001/11/06 21:41:43 roberto Exp $
|
||||
** $Id: ltests.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
|
||||
** Internal Module for Debugging of the Lua Implementation
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -240,13 +240,13 @@ static int mem_query (lua_State *L) {
|
||||
|
||||
static int hash_query (lua_State *L) {
|
||||
if (lua_isnull(L, 2)) {
|
||||
luaL_arg_check(L, lua_tag(L, 1) == LUA_TSTRING, 1, "string expected");
|
||||
luaL_arg_check(L, lua_type(L, 1) == LUA_TSTRING, 1, "string expected");
|
||||
lua_pushnumber(L, tsvalue(luaA_index(L, 1))->tsv.hash);
|
||||
}
|
||||
else {
|
||||
TObject *o = luaA_index(L, 1);
|
||||
Table *t;
|
||||
luaL_check_rawtype(L, 2, LUA_TTABLE);
|
||||
luaL_check_type(L, 2, LUA_TTABLE);
|
||||
t = hvalue(luaA_index(L, 2));
|
||||
lua_pushnumber(L, luaH_mainposition(t, o) - t->node);
|
||||
}
|
||||
@ -257,7 +257,7 @@ static int hash_query (lua_State *L) {
|
||||
static int table_query (lua_State *L) {
|
||||
const Table *t;
|
||||
int i = luaL_opt_int(L, 2, -1);
|
||||
luaL_check_rawtype(L, 1, LUA_TTABLE);
|
||||
luaL_check_type(L, 1, LUA_TTABLE);
|
||||
t = hvalue(luaA_index(L, 1));
|
||||
if (i == -1) {
|
||||
lua_pushnumber(L, t->sizearray);
|
||||
@ -333,6 +333,18 @@ static int unref (lua_State *L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int eventtable (lua_State *L) {
|
||||
luaL_check_any(L, 1);
|
||||
if (lua_isnull(L, 2))
|
||||
lua_geteventtable(L, 1);
|
||||
else {
|
||||
lua_settop(L, 2);
|
||||
luaL_check_type(L, 2, LUA_TTABLE);
|
||||
lua_seteventtable(L, 1);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int newuserdata (lua_State *L) {
|
||||
size_t size = luaL_check_int(L, 1);
|
||||
char *p = cast(char *, lua_newuserdata(L, size));
|
||||
@ -345,24 +357,13 @@ static int newuserdatabox (lua_State *L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int settag (lua_State *L) {
|
||||
luaL_check_any(L, 1);
|
||||
lua_pushvalue(L, 1); /* push value */
|
||||
lua_settag(L, luaL_check_int(L, 2));
|
||||
return 1; /* return value */
|
||||
}
|
||||
|
||||
static int udataval (lua_State *L) {
|
||||
luaL_check_rawtype(L, 1, LUA_TUSERDATA);
|
||||
luaL_check_type(L, 1, LUA_TUSERDATA);
|
||||
lua_pushnumber(L, cast(int, lua_touserdata(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int newtag (lua_State *L) {
|
||||
lua_pushnumber(L, lua_newtype(L, lua_tostring(L, 1),
|
||||
cast(int, lua_tonumber(L, 2))));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int doonnewstack (lua_State *L) {
|
||||
lua_State *L1 = lua_newthread(L, luaL_check_int(L, 1));
|
||||
@ -435,16 +436,6 @@ static int doremote (lua_State *L) {
|
||||
}
|
||||
}
|
||||
|
||||
static int settagmethod (lua_State *L) {
|
||||
int tag = luaL_check_int(L, 1);
|
||||
const char *event = luaL_check_string(L, 2);
|
||||
luaL_check_any(L, 3);
|
||||
lua_gettagmethod(L, tag, event);
|
||||
lua_pushvalue(L, 3);
|
||||
lua_settagmethod(L, tag, event);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int log2_aux (lua_State *L) {
|
||||
lua_pushnumber(L, luaO_log2(luaL_check_int(L, 1)));
|
||||
@ -614,18 +605,14 @@ static int testC (lua_State *L) {
|
||||
else if EQ("dostring") {
|
||||
lua_dostring(L, luaL_check_string(L, getnum));
|
||||
}
|
||||
else if EQ("settagmethod") {
|
||||
int tag = getnum;
|
||||
const char *event = getname;
|
||||
lua_settagmethod(L, tag, event);
|
||||
else if EQ("seteventtable") {
|
||||
lua_seteventtable(L, getnum);
|
||||
}
|
||||
else if EQ("gettagmethod") {
|
||||
int tag = getnum;
|
||||
const char *event = getname;
|
||||
lua_gettagmethod(L, tag, event);
|
||||
else if EQ("geteventtable") {
|
||||
lua_geteventtable(L, getnum);
|
||||
}
|
||||
else if EQ("type") {
|
||||
lua_pushstring(L, lua_type(L, getnum));
|
||||
lua_pushstring(L, lua_typename(L, lua_type(L, getnum)));
|
||||
}
|
||||
else luaL_verror(L, "unknown instruction %.30s", buff);
|
||||
}
|
||||
@ -651,16 +638,14 @@ static const struct luaL_reg tests_funcs[] = {
|
||||
{"unref", unref},
|
||||
{"d2s", d2s},
|
||||
{"s2d", s2d},
|
||||
{"eventtable", eventtable},
|
||||
{"newuserdata", newuserdata},
|
||||
{"newuserdatabox", newuserdatabox},
|
||||
{"settag", settag},
|
||||
{"udataval", udataval},
|
||||
{"newtag", newtag},
|
||||
{"doonnewstack", doonnewstack},
|
||||
{"newstate", newstate},
|
||||
{"closestate", closestate},
|
||||
{"doremote", doremote},
|
||||
{"settagmethod", settagmethod},
|
||||
{"log2", log2_aux},
|
||||
{"totalmem", mem_query}
|
||||
};
|
||||
|
175
ltm.c
175
ltm.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ltm.c,v 1.80 2001/10/11 21:41:21 roberto Exp $
|
||||
** $Id: ltm.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
|
||||
** Tag methods
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -10,8 +10,6 @@
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#include "ldo.h"
|
||||
#include "lmem.h"
|
||||
#include "lobject.h"
|
||||
#include "lstate.h"
|
||||
#include "lstring.h"
|
||||
@ -19,161 +17,46 @@
|
||||
#include "ltm.h"
|
||||
|
||||
|
||||
const char *const luaT_eventname[] = { /* ORDER TM */
|
||||
"gettable", "settable", "index", "getglobal",
|
||||
"setglobal", "add", "sub", "mul", "div",
|
||||
"pow", "unm", "lt", "concat", "gc",
|
||||
"function",
|
||||
NULL
|
||||
|
||||
const char *const luaT_typenames[] = {
|
||||
"userdata", "nil", "number", "string", "table", "function"
|
||||
};
|
||||
|
||||
|
||||
static int findevent (const char *name) {
|
||||
int i;
|
||||
for (i=0; luaT_eventname[i]; i++)
|
||||
if (strcmp(luaT_eventname[i], name) == 0)
|
||||
return i;
|
||||
return -1; /* name not found */
|
||||
}
|
||||
|
||||
|
||||
static int luaI_checkevent (lua_State *L, const char *name) {
|
||||
int e = findevent(name);
|
||||
if (e < 0)
|
||||
luaO_verror(L, "`%.50s' is not a valid event name", name);
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* events in LUA_TNIL are all allowed, since this is used as a
|
||||
* `placeholder' for default fallbacks
|
||||
*/
|
||||
/* ORDER LUA_T, ORDER TM */
|
||||
static const lu_byte luaT_validevents[NUM_TAGS][TM_N] = {
|
||||
{1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_TUSERDATA */
|
||||
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_TNIL */
|
||||
{1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, /* LUA_TNUMBER */
|
||||
{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_TSTRING */
|
||||
{0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_TTABLE */
|
||||
{1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0} /* LUA_TFUNCTION */
|
||||
};
|
||||
|
||||
static int luaT_validevent (int t, int e) { /* ORDER LUA_T */
|
||||
return (t >= NUM_TAGS) ? 1 : cast(int, luaT_validevents[t][e]);
|
||||
}
|
||||
|
||||
|
||||
void luaT_init (lua_State *L) {
|
||||
static const char *const typenames[NUM_TAGS] = {
|
||||
"userdata", "nil", "number", "string",
|
||||
"table", "function"
|
||||
static const char *const luaT_eventname[] = { /* ORDER TM */
|
||||
"gettable", "settable", "index",
|
||||
"gc",
|
||||
"add", "sub", "mul", "div",
|
||||
"pow", "unm", "lt", "concat",
|
||||
"call"
|
||||
};
|
||||
int i;
|
||||
for (i=0; i<NUM_TAGS; i++)
|
||||
luaT_newtag(L, typenames[i], i);
|
||||
}
|
||||
|
||||
|
||||
int luaT_newtag (lua_State *L, const char *name, int basictype) {
|
||||
int tag;
|
||||
int i;
|
||||
TString *ts = NULL;
|
||||
luaM_growvector(L, G(L)->TMtable, G(L)->ntag, G(L)->sizeTM, struct TM,
|
||||
MAX_INT, "tag table overflow");
|
||||
tag = G(L)->ntag;
|
||||
if (name) {
|
||||
const TObject *v;
|
||||
TObject otag;
|
||||
ts = luaS_new(L, name);
|
||||
v = luaH_getstr(G(L)->type2tag, ts);
|
||||
if (ttype(v) == LUA_TNUMBER) return cast(int, nvalue(v));
|
||||
setnvalue(&otag, tag);
|
||||
luaH_setstr(L, G(L)->type2tag, ts, &otag);
|
||||
}
|
||||
for (i=0; i<TM_N; i++)
|
||||
luaT_gettm(G(L), tag, i) = NULL;
|
||||
G(L)->TMtable[tag].collected = NULL;
|
||||
G(L)->TMtable[tag].name = ts;
|
||||
G(L)->TMtable[tag].basictype = basictype;
|
||||
G(L)->ntag++;
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
||||
static void checktag (lua_State *L, int tag) {
|
||||
if (!(0 <= tag && tag < G(L)->ntag))
|
||||
luaO_verror(L, "%d is not a valid tag", tag);
|
||||
}
|
||||
|
||||
|
||||
int luaT_tag (const TObject *o) {
|
||||
int t = ttype(o);
|
||||
switch (t) {
|
||||
case LUA_TUSERDATA: return uvalue(o)->uv.tag;
|
||||
case LUA_TTABLE: return hvalue(o)->htag;
|
||||
default: return t;
|
||||
for (i=0; i<TM_N; i++) {
|
||||
G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
|
||||
G(L)->tmname[i]->tsv.marked = FIXMARK; /* never collect these names */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const char *luaT_typename (global_State *G, const TObject *o) {
|
||||
int t = ttype(o);
|
||||
int tag;
|
||||
TString *ts;
|
||||
switch (t) {
|
||||
case LUA_TUSERDATA:
|
||||
tag = uvalue(o)->uv.tag;
|
||||
break;
|
||||
const TObject *luaT_gettm (Table *events, TMS event, TString *ename) {
|
||||
const TObject *tm = luaH_getstr(events, ename);
|
||||
if (ttype(tm) == LUA_TNIL) { /* no tag method? */
|
||||
events->flags |= (1<<event); /* cache this fact */
|
||||
return NULL;
|
||||
}
|
||||
else return tm;
|
||||
}
|
||||
|
||||
|
||||
const TObject *luaT_gettmbyobj (lua_State *L, const TObject *o, TMS event) {
|
||||
switch (ttype(o)) {
|
||||
case LUA_TTABLE:
|
||||
tag = hvalue(o)->htag;
|
||||
break;
|
||||
return fasttm(L, hvalue(o)->eventtable, event);
|
||||
case LUA_TUSERDATA:
|
||||
return fasttm(L, uvalue(o)->uv.eventtable, event);
|
||||
default:
|
||||
tag = t;
|
||||
return NULL;
|
||||
}
|
||||
ts = G->TMtable[tag].name;
|
||||
if (ts == NULL)
|
||||
ts = G->TMtable[t].name;
|
||||
return getstr(ts);
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_gettagmethod (lua_State *L, int t, const char *event) {
|
||||
int e;
|
||||
lua_lock(L);
|
||||
e = luaI_checkevent(L, event);
|
||||
checktag(L, t);
|
||||
if (luaT_validevent(t, e) && luaT_gettm(G(L), t, e)) {
|
||||
setclvalue(L->top, luaT_gettm(G(L), t, e));
|
||||
}
|
||||
else
|
||||
setnilvalue(L->top);
|
||||
incr_top;
|
||||
lua_unlock(L);
|
||||
}
|
||||
|
||||
|
||||
LUA_API void lua_settagmethod (lua_State *L, int t, const char *event) {
|
||||
int e;
|
||||
lua_lock(L);
|
||||
e = luaI_checkevent(L, event);
|
||||
checktag(L, t);
|
||||
if (!luaT_validevent(t, e))
|
||||
luaO_verror(L, "cannot change `%.20s' tag method for type `%.20s'%.20s",
|
||||
luaT_eventname[e], typenamebytag(G(L), t),
|
||||
(t == LUA_TTABLE || t == LUA_TUSERDATA) ?
|
||||
" with default tag" : "");
|
||||
switch (ttype(L->top - 1)) {
|
||||
case LUA_TNIL:
|
||||
luaT_gettm(G(L), t, e) = NULL;
|
||||
break;
|
||||
case LUA_TFUNCTION:
|
||||
luaT_gettm(G(L), t, e) = clvalue(L->top - 1);
|
||||
break;
|
||||
default:
|
||||
luaD_error(L, "tag method must be a function (or nil)");
|
||||
}
|
||||
L->top--;
|
||||
lua_unlock(L);
|
||||
}
|
||||
|
||||
|
49
ltm.h
49
ltm.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: ltm.h,v 1.28 2001/10/02 16:43:54 roberto Exp $
|
||||
** $Id: ltm.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
|
||||
** Tag methods
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -9,7 +9,6 @@
|
||||
|
||||
|
||||
#include "lobject.h"
|
||||
#include "lstate.h"
|
||||
|
||||
/*
|
||||
* WARNING: if you change the order of this enumeration,
|
||||
@ -19,8 +18,7 @@ typedef enum {
|
||||
TM_GETTABLE = 0,
|
||||
TM_SETTABLE,
|
||||
TM_INDEX,
|
||||
TM_GETGLOBAL,
|
||||
TM_SETGLOBAL,
|
||||
TM_GC,
|
||||
TM_ADD,
|
||||
TM_SUB,
|
||||
TM_MUL,
|
||||
@ -29,51 +27,20 @@ typedef enum {
|
||||
TM_UNM,
|
||||
TM_LT,
|
||||
TM_CONCAT,
|
||||
TM_GC,
|
||||
TM_FUNCTION,
|
||||
TM_CALL,
|
||||
TM_N /* number of elements in the enum */
|
||||
} TMS;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** masks for allowable tag methods
|
||||
** (see `luaT_validevents')
|
||||
*/
|
||||
#define HAS_TM_GETGLOBAL(L,t) ((1<<(t)) & ((1<<LUA_TUSERDATA) | \
|
||||
(1<<LUA_TTABLE) | \
|
||||
(1<<LUA_TNIL)))
|
||||
|
||||
#define HAS_TM_SETGLOBAL(L,t) ((1<<(t)) & ((1<<LUA_TUSERDATA) | \
|
||||
(1<<LUA_TTABLE) | \
|
||||
(1<<LUA_TNIL) | \
|
||||
(1<<LUA_TFUNCTION)))
|
||||
|
||||
|
||||
|
||||
struct TM {
|
||||
Closure *method[TM_N];
|
||||
Udata *collected; /* list of garbage-collected udata with this tag */
|
||||
TString *name; /* type name */
|
||||
int basictype;
|
||||
};
|
||||
|
||||
|
||||
#define luaT_gettm(G,tag,event) (G->TMtable[tag].method[event])
|
||||
#define luaT_gettmbyObj(G,o,e) (luaT_gettm((G),luaT_tag(o),(e)))
|
||||
|
||||
#define typenamebytag(G, t) getstr(G->TMtable[t].name)
|
||||
|
||||
|
||||
#define validtag(G,t) (NUM_TAGS <= (t) && (t) < G->ntag)
|
||||
|
||||
extern const char *const luaT_eventname[];
|
||||
#define fasttm(l,et,e) \
|
||||
(((et)->flags & (1<<(e))) ? NULL : luaT_gettm(et, e, G(l)->tmname[e]))
|
||||
|
||||
|
||||
const TObject *luaT_gettm (Table *events, TMS event, TString *ename);
|
||||
const TObject *luaT_gettmbyobj (lua_State *L, const TObject *o, TMS event);
|
||||
void luaT_init (lua_State *L);
|
||||
int luaT_newtag (lua_State *L, const char *name, int basictype);
|
||||
const char *luaT_typename (global_State *G, const TObject *o);
|
||||
int luaT_tag (const TObject *o);
|
||||
|
||||
extern const char *const luaT_typenames[];
|
||||
|
||||
#endif
|
||||
|
36
lua.h
36
lua.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lua.h,v 1.107 2001/10/31 19:58:11 roberto Exp $
|
||||
** $Id: lua.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
|
||||
** Lua - An Extensible Extension Language
|
||||
** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
|
||||
** e-mail: info@lua.org
|
||||
@ -55,15 +55,11 @@ typedef struct lua_State lua_State;
|
||||
typedef int (*lua_CFunction) (lua_State *L);
|
||||
|
||||
|
||||
/*
|
||||
** an invalid `tag'
|
||||
*/
|
||||
#define LUA_NOTAG (-1)
|
||||
|
||||
/*
|
||||
** tags for basic types
|
||||
** basic types
|
||||
*/
|
||||
#define LUA_TNONE LUA_NOTAG
|
||||
#define LUA_TNONE (-1)
|
||||
|
||||
#define LUA_TUSERDATA 0
|
||||
#define LUA_TNIL 1
|
||||
@ -120,12 +116,11 @@ LUA_API int lua_stackspace (lua_State *L);
|
||||
** access functions (stack -> C)
|
||||
*/
|
||||
|
||||
LUA_API const char *lua_type (lua_State *L, int index);
|
||||
LUA_API int lua_isnumber (lua_State *L, int index);
|
||||
LUA_API int lua_isstring (lua_State *L, int index);
|
||||
LUA_API int lua_iscfunction (lua_State *L, int index);
|
||||
LUA_API int lua_tag (lua_State *L, int index);
|
||||
LUA_API int lua_rawtag (lua_State *L, int index);
|
||||
LUA_API int lua_type (lua_State *L, int index);
|
||||
LUA_API const char *lua_typename (lua_State *L, int type);
|
||||
|
||||
LUA_API int lua_equal (lua_State *L, int index1, int index2);
|
||||
LUA_API int lua_lessthan (lua_State *L, int index1, int index2);
|
||||
@ -155,9 +150,9 @@ LUA_API void lua_getglobal (lua_State *L, const char *name);
|
||||
LUA_API void lua_gettable (lua_State *L, int index);
|
||||
LUA_API void lua_rawget (lua_State *L, int index);
|
||||
LUA_API void lua_rawgeti (lua_State *L, int index, int n);
|
||||
LUA_API void lua_gettagmethod (lua_State *L, int tag, const char *event);
|
||||
LUA_API void lua_newtable (lua_State *L);
|
||||
LUA_API void lua_getweakregistry (lua_State *L);
|
||||
LUA_API void lua_geteventtable (lua_State *L, int objindex);
|
||||
|
||||
|
||||
/*
|
||||
@ -168,7 +163,7 @@ LUA_API void lua_settable (lua_State *L, int index);
|
||||
LUA_API void lua_rawset (lua_State *L, int index);
|
||||
LUA_API void lua_rawseti (lua_State *L, int index, int n);
|
||||
LUA_API void lua_setglobals (lua_State *L);
|
||||
LUA_API void lua_settagmethod (lua_State *L, int tag, const char *event);
|
||||
LUA_API void lua_seteventtable (lua_State *L, int objindex);
|
||||
|
||||
|
||||
/*
|
||||
@ -194,11 +189,6 @@ LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold);
|
||||
/*
|
||||
** miscellaneous functions
|
||||
*/
|
||||
LUA_API int lua_newtype (lua_State *L, const char *name, int basictype);
|
||||
LUA_API void lua_settag (lua_State *L, int tag);
|
||||
|
||||
LUA_API int lua_name2tag (lua_State *L, const char *name);
|
||||
LUA_API const char *lua_tag2name (lua_State *L, int tag);
|
||||
|
||||
LUA_API void lua_error (lua_State *L, const char *s);
|
||||
|
||||
@ -228,11 +218,11 @@ LUA_API int lua_getweakmode (lua_State *L, int index);
|
||||
#define lua_register(L,n,f) (lua_pushcfunction(L, f), lua_setglobal(L, n))
|
||||
#define lua_pushcfunction(L,f) lua_pushcclosure(L, f, 0)
|
||||
|
||||
#define lua_isfunction(L,n) (lua_rawtag(L,n) == LUA_TFUNCTION)
|
||||
#define lua_istable(L,n) (lua_rawtag(L,n) == LUA_TTABLE)
|
||||
#define lua_isuserdata(L,n) (lua_rawtag(L,n) == LUA_TUSERDATA)
|
||||
#define lua_isnil(L,n) (lua_rawtag(L,n) == LUA_TNIL)
|
||||
#define lua_isnull(L,n) (lua_rawtag(L,n) == LUA_TNONE)
|
||||
#define lua_isfunction(L,n) (lua_type(L,n) == LUA_TFUNCTION)
|
||||
#define lua_istable(L,n) (lua_type(L,n) == LUA_TTABLE)
|
||||
#define lua_isuserdata(L,n) (lua_type(L,n) == LUA_TUSERDATA)
|
||||
#define lua_isnil(L,n) (lua_type(L,n) == LUA_TNIL)
|
||||
#define lua_isnull(L,n) (lua_type(L,n) == LUA_TNONE)
|
||||
|
||||
#define lua_pushliteral(L, s) lua_pushlstring(L, "" s, \
|
||||
(sizeof(s)/sizeof(char))-1)
|
||||
@ -245,8 +235,6 @@ LUA_API int lua_getweakmode (lua_State *L, int index);
|
||||
/*
|
||||
** compatibility macros and functions
|
||||
*/
|
||||
#define lua_newtag(L) lua_newtype(L, NULL, LUA_TNONE)
|
||||
#define lua_typename lua_tag2name
|
||||
|
||||
LUA_API void lua_pushupvalues (lua_State *L);
|
||||
|
||||
|
137
lvm.c
137
lvm.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lvm.c,v 1.198 2001/11/06 21:41:53 roberto Exp $
|
||||
** $Id: lvm.c,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
|
||||
** Lua virtual machine
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -85,69 +85,66 @@ static void traceexec (lua_State *L, lua_Hook linehook) {
|
||||
/* maximum stack used by a call to a tag method (func + args) */
|
||||
#define MAXSTACK_TM 4
|
||||
|
||||
static StkId callTM (lua_State *L, Closure *f, const char *fmt, ...) {
|
||||
va_list argp;
|
||||
static void callTM (lua_State *L, const TObject *f,
|
||||
const TObject *p1, const TObject *p2, const TObject *p3, TObject *result ) {
|
||||
StkId base = L->top;
|
||||
lua_assert(strlen(fmt)+1 <= MAXSTACK_TM);
|
||||
luaD_checkstack(L, MAXSTACK_TM);
|
||||
va_start(argp, fmt);
|
||||
setclvalue(L->top, f); /* push function */
|
||||
L->top++;
|
||||
while (*fmt) {
|
||||
if (*fmt++ == 'o') {
|
||||
setobj(L->top, va_arg(argp, TObject *));
|
||||
}
|
||||
else {
|
||||
lua_assert(*(fmt-1) == 's');
|
||||
setsvalue(L->top, va_arg(argp, TString *));
|
||||
}
|
||||
setobj(base, f); /* push function */
|
||||
setobj(base+1, p1); /* 1st argument */
|
||||
setobj(base+2, p2); /* 2nd argument */
|
||||
L->top += 3;
|
||||
if (p3) {
|
||||
setobj(base+3, p3); /* 3th argument */
|
||||
L->top++;
|
||||
}
|
||||
luaD_call(L, base);
|
||||
va_end(argp);
|
||||
return base;
|
||||
}
|
||||
|
||||
|
||||
#define setTM(L, base) (L->top = (base))
|
||||
|
||||
static void setTMresult (lua_State *L, TObject *result, StkId base) {
|
||||
if (L->top == base) { /* are there valid results? */
|
||||
setnilvalue(result); /* function had no results */
|
||||
}
|
||||
else {
|
||||
setobj(result, base); /* get first result */
|
||||
if (result) { /* need a result? */
|
||||
if (L->top == base) { /* are there valid results? */
|
||||
setnilvalue(result); /* function had no results */
|
||||
}
|
||||
else {
|
||||
setobj(result, base); /* get first result */
|
||||
}
|
||||
}
|
||||
L->top = base; /* restore top */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** Function to index a table.
|
||||
** Receives the table at `t' and the key at the `key'.
|
||||
** leaves the result at `res'.
|
||||
*/
|
||||
void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) {
|
||||
Closure *tm;
|
||||
const TObject *tm;
|
||||
init:
|
||||
if (ttype(t) == LUA_TTABLE) { /* `t' is a table? */
|
||||
int tg = hvalue(t)->htag;
|
||||
if (tg == LUA_TTABLE || /* with default tag? */
|
||||
(tm = luaT_gettm(G(L), tg, TM_GETTABLE)) == NULL) { /* or no TM? */
|
||||
Table *et = hvalue(t)->eventtable;
|
||||
if ((tm = fasttm(L, et, TM_GETTABLE)) == NULL) { /* no gettable TM? */
|
||||
const TObject *h = luaH_get(hvalue(t), key); /* do a primitive get */
|
||||
/* result is no nil or there is no `index' tag method? */
|
||||
if (ttype(h) != LUA_TNIL || /* no nil? */
|
||||
((tm=luaT_gettm(G(L), tg, TM_INDEX)) == NULL)) { /* or no index TM? */
|
||||
(tm = fasttm(L, et, TM_INDEX)) == NULL) { /* or no index TM? */
|
||||
setobj(res, h); /* default get */
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* else will call the tag method */
|
||||
} else { /* not a table; try a `gettable' tag method */
|
||||
tm = luaT_gettmbyObj(G(L), t, TM_GETTABLE);
|
||||
if (tm == NULL) /* no tag method? */
|
||||
if (ttype(t) != LUA_TUSERDATA ||
|
||||
(tm = fasttm(L, uvalue(t)->uv.eventtable, TM_GETTABLE)) == NULL) {
|
||||
luaG_typeerror(L, t, "index");
|
||||
return; /* to avoid warnings */
|
||||
}
|
||||
}
|
||||
lua_assert(tm != NULL);
|
||||
if (ttype(tm) == LUA_TFUNCTION)
|
||||
callTM(L, tm, t, key, NULL, res);
|
||||
else {
|
||||
t = tm;
|
||||
goto init; /* return luaV_gettable(L, tm, key, res); */
|
||||
}
|
||||
setTMresult(L, res, callTM(L, tm, "oo", t, key));
|
||||
}
|
||||
|
||||
|
||||
@ -156,63 +153,44 @@ void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) {
|
||||
** Receives table at `t', key at `key' and value at `val'.
|
||||
*/
|
||||
void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val) {
|
||||
Closure *tm;
|
||||
const TObject *tm;
|
||||
init:
|
||||
if (ttype(t) == LUA_TTABLE) { /* `t' is a table? */
|
||||
int tg = hvalue(t)->htag;
|
||||
if (hvalue(t)->htag == LUA_TTABLE || /* with default tag? */
|
||||
(tm = luaT_gettm(G(L), tg, TM_SETTABLE)) == NULL) { /* or no TM? */
|
||||
Table *et = hvalue(t)->eventtable;
|
||||
if ((tm = fasttm(L, et, TM_SETTABLE)) == NULL) { /* no TM? */
|
||||
luaH_set(L, hvalue(t), key, val); /* do a primitive set */
|
||||
return;
|
||||
}
|
||||
/* else will call the tag method */
|
||||
} else { /* not a table; try a `settable' tag method */
|
||||
tm = luaT_gettmbyObj(G(L), t, TM_SETTABLE);
|
||||
if (tm == NULL) /* no tag method? */
|
||||
if (ttype(t) != LUA_TUSERDATA ||
|
||||
(tm = fasttm(L, uvalue(t)->uv.eventtable, TM_SETTABLE)) == NULL) {
|
||||
luaG_typeerror(L, t, "index");
|
||||
return; /* to avoid warnings */
|
||||
}
|
||||
}
|
||||
setTM(L, callTM(L, tm, "ooo", t, key, val));
|
||||
}
|
||||
|
||||
|
||||
void luaV_getglobal (lua_State *L, TString *name, StkId res) {
|
||||
const TObject *value = luaH_getstr(hvalue(&L->gt), name);
|
||||
Closure *tm;
|
||||
if (!HAS_TM_GETGLOBAL(L, ttype(value)) || /* is there a tag method? */
|
||||
(tm = luaT_gettmbyObj(G(L), value, TM_GETGLOBAL)) == NULL) {
|
||||
setobj(res, value); /* default behavior */
|
||||
lua_assert(tm != NULL);
|
||||
if (ttype(tm) == LUA_TFUNCTION)
|
||||
callTM(L, tm, t, key, val, NULL);
|
||||
else {
|
||||
t = tm;
|
||||
goto init; /* luaV_settable(L, tm, key, val); */
|
||||
}
|
||||
else
|
||||
setTMresult(L, res, callTM(L, tm, "so", name, value));
|
||||
}
|
||||
|
||||
|
||||
void luaV_setglobal (lua_State *L, TString *name, StkId val) {
|
||||
const TObject *oldvalue = luaH_getstr(hvalue(&L->gt), name);
|
||||
Closure *tm;
|
||||
if (!HAS_TM_SETGLOBAL(L, ttype(oldvalue)) || /* no tag methods? */
|
||||
(tm = luaT_gettmbyObj(G(L), oldvalue, TM_SETGLOBAL)) == NULL) {
|
||||
if (oldvalue == &luaO_nilobject)
|
||||
luaH_setstr(L, hvalue(&L->gt), name, val); /* raw set */
|
||||
else
|
||||
settableval(oldvalue, val); /* warning: tricky optimization! */
|
||||
}
|
||||
else
|
||||
setTM(L, callTM(L, tm, "soo", name, oldvalue, val));
|
||||
}
|
||||
|
||||
|
||||
static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2,
|
||||
TObject *res, TMS event) {
|
||||
Closure *tm = luaT_gettmbyObj(G(L), p1, event); /* try first operand */
|
||||
const TObject *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
|
||||
if (tm == NULL) {
|
||||
tm = luaT_gettmbyObj(G(L), p2, event); /* try second operand */
|
||||
tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
|
||||
if (tm == NULL) {
|
||||
tm = luaT_gettm(G(L), 0, event); /* try a `global' method */
|
||||
if (tm == NULL)
|
||||
return 0; /* no tag method */
|
||||
tm = fasttm(L, hvalue(gt(L)), event);
|
||||
if (tm == NULL) return 0; /* no tag method */
|
||||
}
|
||||
}
|
||||
setTMresult(L, res, callTM(L, tm, "oo", p1, p2));
|
||||
if (ttype(tm) != LUA_TFUNCTION) return 0;
|
||||
callTM(L, tm, p1, p2, NULL, res);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -295,12 +273,13 @@ void luaV_strconc (lua_State *L, int total, StkId top) {
|
||||
static void luaV_pack (lua_State *L, StkId firstelem) {
|
||||
int i;
|
||||
Table *htab = luaH_new(L, 0, 0);
|
||||
TObject n;
|
||||
TObject n, nname;
|
||||
for (i=0; firstelem+i<L->top; i++)
|
||||
luaH_setnum(L, htab, i+1, firstelem+i);
|
||||
/* store counter in field `n' */
|
||||
setnvalue(&n, i);
|
||||
luaH_setstr(L, htab, luaS_newliteral(L, "n"), &n);
|
||||
setsvalue(&nname, luaS_newliteral(L, "n"));
|
||||
luaH_set(L, htab, &nname, &n);
|
||||
L->top = firstelem; /* remove elements from the stack */
|
||||
sethvalue(L->top, htab);
|
||||
incr_top;
|
||||
@ -395,7 +374,7 @@ StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) {
|
||||
}
|
||||
case OP_GETGLOBAL: {
|
||||
lua_assert(ttype(KBc(i)) == LUA_TSTRING);
|
||||
luaV_getglobal(L, tsvalue(KBc(i)), ra);
|
||||
luaV_gettable(L, gt(L), KBc(i), ra);
|
||||
break;
|
||||
}
|
||||
case OP_GETTABLE: {
|
||||
@ -404,7 +383,7 @@ StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) {
|
||||
}
|
||||
case OP_SETGLOBAL: {
|
||||
lua_assert(ttype(KBc(i)) == LUA_TSTRING);
|
||||
luaV_setglobal(L, tsvalue(KBc(i)), ra);
|
||||
luaV_settable(L, gt(L), KBc(i), ra);
|
||||
break;
|
||||
}
|
||||
case OP_SETUPVAL: {
|
||||
|
4
lvm.h
4
lvm.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lvm.h,v 1.31 2001/09/07 17:39:10 roberto Exp $
|
||||
** $Id: lvm.h,v 1.1 2001/11/29 22:14:34 rieru Exp rieru $
|
||||
** Lua virtual machine
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@ -20,8 +20,6 @@ const TObject *luaV_tonumber (const TObject *obj, TObject *n);
|
||||
int luaV_tostring (lua_State *L, TObject *obj);
|
||||
void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res);
|
||||
void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val);
|
||||
void luaV_getglobal (lua_State *L, TString *s, StkId res);
|
||||
void luaV_setglobal (lua_State *L, TString *s, StkId val);
|
||||
StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base);
|
||||
int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r);
|
||||
void luaV_strconc (lua_State *L, int total, StkId top);
|
||||
|
Loading…
Reference in New Issue
Block a user