commit 592a309177edc52847b1196969ad6d49ba21f4fb
parent 413fc7334bf8ceaea71417d73edef15c99d3a793
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Wed, 5 Dec 2001 18:14:56 -0200
tag system replaced by event tables
Diffstat:
M | lapi.c | | | 150 | +++++++++++++++++++++++++++++++------------------------------------------------ |
M | lauxlib.c | | | 19 | ++++++------------- |
M | lauxlib.h | | | 6 | ++---- |
M | lbaselib.c | | | 138 | +++++++++++++++++++++++-------------------------------------------------------- |
M | ldebug.c | | | 29 | ++++++----------------------- |
M | ldo.c | | | 21 | ++++++++++++--------- |
M | lfunc.c | | | 4 | +--- |
M | lgc.c | | | 121 | ++++++++++++++++++++++++++++++++++++++++--------------------------------------- |
M | lgc.h | | | 4 | ++-- |
M | liolib.c | | | 58 | +++++++++++++++++++++++++++++++++++++++++++--------------- |
M | lmathlib.c | | | 5 | ++--- |
M | lobject.h | | | 22 | +++++----------------- |
M | lstate.c | | | 21 | +++++++++++---------- |
M | lstate.h | | | 34 | ++++++++++++++++++++++++---------- |
M | lstring.c | | | 8 | +++++--- |
M | lstrlib.c | | | 4 | ++-- |
M | ltable.c | | | 19 | ++++--------------- |
M | ltable.h | | | 3 | +-- |
M | ltests.c | | | 61 | +++++++++++++++++++++++-------------------------------------- |
M | ltm.c | | | 165 | ++++++++++++------------------------------------------------------------------- |
M | ltm.h | | | 49 | ++++++++----------------------------------------- |
M | lua.h | | | 36 | ++++++++++++------------------------ |
M | lvm.c | | | 137 | ++++++++++++++++++++++++++++++++++--------------------------------------------- |
M | lvm.h | | | 4 | +--- |
24 files changed, 412 insertions(+), 706 deletions(-)
diff --git a/lapi.c b/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);
diff --git a/lauxlib.c b/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);
diff --git a/lauxlib.h b/lauxlib.h
@@ -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,
diff --git a/lbaselib.c b/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},
diff --git a/ldebug.c b/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
diff --git a/ldo.c b/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;
diff --git a/lfunc.c b/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;
}
}
diff --git a/lgc.c b/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);
}
diff --git a/lgc.h b/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);
diff --git a/liolib.c b/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;
}
diff --git a/lmathlib.c b/lmathlib.c
@@ -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;
diff --git a/lobject.h b/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) */
diff --git a/lstate.c b/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);
}
diff --git a/lstate.h b/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;
diff --git a/lstring.c b/lstring.c
@@ -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;
diff --git a/lstrlib.c b/lstrlib.c
@@ -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++) {
diff --git a/ltable.c b/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;
}
diff --git a/ltable.h b/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);
diff --git a/ltests.c b/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}
};
diff --git a/ltm.c b/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
-};
-
-
-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 */
+const char *const luaT_typenames[] = {
+ "userdata", "nil", "number", "string", "table", "function"
};
-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++) {
+ G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
+ G(L)->tmname[i]->tsv.marked = FIXMARK; /* never collect these names */
}
- 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;
+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 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_gettmbyobj (lua_State *L, const TObject *o, TMS event) {
+ switch (ttype(o)) {
case LUA_TTABLE:
- tag = hvalue(o)->htag;
- break;
- default:
- tag = t;
- }
- 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;
+ return fasttm(L, hvalue(o)->eventtable, event);
+ case LUA_TUSERDATA:
+ return fasttm(L, uvalue(o)->uv.eventtable, event);
default:
- luaD_error(L, "tag method must be a function (or nil)");
+ return NULL;
}
- L->top--;
- lua_unlock(L);
}
diff --git a/ltm.h b/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
diff --git a/lua.h b/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);
diff --git a/lvm.c b/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 */
- }
- 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! */
+ 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
- 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: {
diff --git a/lvm.h b/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);