Browse Source

tag system replaced by event tables

Roberto Ierusalimschy 24 years ago
parent
commit
592a309177
24 changed files with 412 additions and 706 deletions
  1. 59 91
      lapi.c
  2. 6 13
      lauxlib.c
  3. 2 4
      lauxlib.h
  4. 40 98
      lbaselib.c
  5. 6 23
      ldebug.c
  6. 12 9
      ldo.c
  7. 1 3
      lfunc.c
  8. 61 60
      lgc.c
  9. 2 2
      lgc.h
  10. 43 15
      liolib.c
  11. 2 3
      lmathlib.c
  12. 5 17
      lobject.h
  13. 11 10
      lstate.c
  14. 24 10
      lstate.h
  15. 5 3
      lstring.c
  16. 2 2
      lstrlib.c
  17. 4 15
      ltable.c
  18. 1 2
      ltable.h
  19. 23 38
      ltests.c
  20. 24 141
      ltm.c
  21. 8 41
      ltm.h
  22. 12 24
      lua.h
  23. 58 79
      lvm.c
  24. 1 3
      lvm.h

+ 59 - 91
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
 ** Lua API
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -45,8 +45,8 @@ static TObject *negindex (lua_State *L, int index) {
     return L->top+index;
     return L->top+index;
   }
   }
   else switch (index) {  /* pseudo-indices */
   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: {
     default: {
       TObject *func = (L->ci->base - 1);
       TObject *func = (L->ci->base - 1);
       index = LUA_GLOBALSINDEX - index;
       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);
   StkId o = luaA_indexAcceptable(L, index);
   return (o == NULL) ? LUA_TNONE : ttype(o);
   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) {
 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);
   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) {
 LUA_API int lua_equal (lua_State *L, int index1, int index2) {
   StkId o1 = luaA_indexAcceptable(L, index1);
   StkId o1 = luaA_indexAcceptable(L, index1);
   StkId o2 = luaA_indexAcceptable(L, index2);
   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) {
 LUA_API void lua_getglobal (lua_State *L, const char *name) {
+  TObject o;
   lua_lock(L);
   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);
   api_incr_top(L);
   lua_unlock(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)
 ** 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) {
 LUA_API void lua_setglobal (lua_State *L, const char *name) {
+  TObject o;
   lua_lock(L);
   lua_lock(L);
   api_checknelems(L, 1);
   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 */
   L->top--;  /* remove element from the top */
   lua_unlock(L);
   lua_unlock(L);
 }
 }
@@ -447,11 +458,32 @@ LUA_API void lua_setglobals (lua_State *L) {
   api_checknelems(L, 1);
   api_checknelems(L, 1);
   newtable = --L->top;
   newtable = --L->top;
   api_check(L, ttype(newtable) == LUA_TTABLE);
   api_check(L, ttype(newtable) == LUA_TTABLE);
-  setobj(&L->gt, newtable);
+  setobj(gt(L), newtable);
   lua_unlock(L);
   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)
 ** `do' functions (run Lua code)
@@ -533,70 +565,6 @@ LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) {
 ** miscellaneous functions
 ** 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_API void lua_error (lua_State *L, const char *s) {
   lua_lock(L);
   lua_lock(L);

+ 6 - 13
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
 ** Auxiliary functions for building Lua libraries
 ** See Copyright Notice in lua.h
 ** 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) {
 LUALIB_API void luaL_typerror (lua_State *L, int narg, const char *tname) {
   char buff[80];
   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);
   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);
     tag_error(L, narg, t);
 }
 }
 
 
 
 
 LUALIB_API void luaL_check_any (lua_State *L, int narg) {
 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");
     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) {
 LUALIB_API const char *luaL_check_lstr (lua_State *L, int narg, size_t *len) {
   const char *s = lua_tostring(L, narg);
   const char *s = lua_tostring(L, narg);
   if (!s) tag_error(L, narg, LUA_TSTRING);
   if (!s) tag_error(L, narg, LUA_TSTRING);

+ 2 - 4
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
 ** Auxiliary functions for building Lua libraries
 ** See Copyright Notice in lua.h
 ** 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 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_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_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 void luaL_verror (lua_State *L, const char *fmt, ...);
 LUALIB_API int luaL_findstring (const char *name, 
 LUALIB_API int luaL_findstring (const char *name, 

+ 40 - 98
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
 ** Basic library
 ** See Copyright Notice in lua.h
 ** 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.
 ** The library `liolib' redefines _ERRORMESSAGE for better error information.
 */
 */
 static int luaB__ERRORMESSAGE (lua_State *L) {
 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);
   lua_getglobal(L, LUA_ALERT);
   if (lua_isfunction(L, -1)) {  /* avoid error loop if _ALERT is not defined */
   if (lua_isfunction(L, -1)) {  /* avoid error loop if _ALERT is not defined */
     lua_Debug ar;
     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;
   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) {
 static int luaB_weakmode (lua_State *L) {
   const char *mode = luaL_check_string(L, 2);
   const char *mode = luaL_check_string(L, 2);
-  luaL_check_rawtype(L, 1, LUA_TTABLE);
+  luaL_check_type(L, 1, LUA_TTABLE);
   if (*mode == '?') {
   if (*mode == '?') {
     char buff[3];
     char buff[3];
     char *s = buff;
     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) {
 static int luaB_globals (lua_State *L) {
   lua_getglobals(L);  /* value to be returned */
   lua_getglobals(L);  /* value to be returned */
   if (!lua_isnull(L, 1)) {
   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_pushvalue(L, 1);  /* new table of globals */
     lua_setglobals(L);
     lua_setglobals(L);
   }
   }
@@ -209,43 +184,20 @@ static int luaB_globals (lua_State *L) {
 }
 }
 
 
 static int luaB_rawget (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);
   luaL_check_any(L, 2);
   lua_rawget(L, -2);
   lua_rawget(L, -2);
   return 1;
   return 1;
 }
 }
 
 
 static int luaB_rawset (lua_State *L) {
 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, 2);
   luaL_check_any(L, 3);
   luaL_check_any(L, 3);
   lua_rawset(L, -3);
   lua_rawset(L, -3);
   return 1;
   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) {
 static int luaB_gcinfo (lua_State *L) {
   lua_pushnumber(L, lua_getgccount(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) {
 static int luaB_type (lua_State *L) {
   luaL_check_any(L, 1);
   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;
   return 1;
 }
 }
 
 
 
 
 static int luaB_next (lua_State *L) {
 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 */
   lua_settop(L, 2);  /* create a 2nd argument if there isn't one */
   if (lua_next(L, 1))
   if (lua_next(L, 1))
     return 2;
     return 2;
@@ -393,7 +345,7 @@ static int luaB_require (lua_State *L) {
 
 
 static int aux_unpack (lua_State *L, int arg) {
 static int aux_unpack (lua_State *L, int arg) {
   int n, i;
   int n, i;
-  luaL_check_rawtype(L, arg, LUA_TTABLE);
+  luaL_check_type(L, arg, LUA_TTABLE);
   n = lua_getn(L, arg);
   n = lua_getn(L, arg);
   luaL_check_stack(L, n, "table too big to unpack");
   luaL_check_stack(L, n, "table too big to unpack");
   for (i=1; i<=n; i++)  /* push arg[1...n] */
   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) {
 static int luaB_tostring (lua_State *L) {
   char buff[64];
   char buff[64];
-  switch (lua_rawtag(L, 1)) {
+  switch (lua_type(L, 1)) {
     case LUA_TNUMBER:
     case LUA_TNUMBER:
       lua_pushstring(L, lua_tostring(L, 1));
       lua_pushstring(L, lua_tostring(L, 1));
       return 1;
       return 1;
@@ -451,16 +403,15 @@ static int luaB_tostring (lua_State *L) {
       lua_pushvalue(L, 1);
       lua_pushvalue(L, 1);
       return 1;
       return 1;
     case LUA_TTABLE:
     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;
       break;
     case LUA_TFUNCTION:
     case LUA_TFUNCTION:
       sprintf(buff, "function: %p", lua_topointer(L, 1));
       sprintf(buff, "function: %p", lua_topointer(L, 1));
       break;
       break;
     case LUA_TUSERDATA: {
     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)
       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
       else
         sprintf(buff, "%.40s: %p", t, lua_touserdata(L, 1));
         sprintf(buff, "%.40s: %p", t, lua_touserdata(L, 1));
       break;
       break;
@@ -478,8 +429,8 @@ static int luaB_tostring (lua_State *L) {
 
 
 static int luaB_foreachi (lua_State *L) {
 static int luaB_foreachi (lua_State *L) {
   int n, i;
   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);
   n = lua_getn(L, 1);
   for (i=1; i<=n; i++) {
   for (i=1; i<=n; i++) {
     lua_pushvalue(L, 2);  /* function */
     lua_pushvalue(L, 2);  /* function */
@@ -495,8 +446,8 @@ static int luaB_foreachi (lua_State *L) {
 
 
 
 
 static int luaB_foreach (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 */
   lua_pushnil(L);  /* first index */
   for (;;) {
   for (;;) {
     if (lua_next(L, 1) == 0)
     if (lua_next(L, 1) == 0)
@@ -523,7 +474,7 @@ static int luaB_assert (lua_State *L) {
 
 
 
 
 static int luaB_getn (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));
   lua_pushnumber(L, lua_getn(L, 1));
   return 1;
   return 1;
 }
 }
@@ -532,7 +483,7 @@ static int luaB_getn (lua_State *L) {
 static int luaB_tinsert (lua_State *L) {
 static int luaB_tinsert (lua_State *L) {
   int v = lua_gettop(L);  /* number of arguments */
   int v = lua_gettop(L);  /* number of arguments */
   int n, pos;
   int n, pos;
-  luaL_check_rawtype(L, 1, LUA_TTABLE);
+  luaL_check_type(L, 1, LUA_TTABLE);
   n = lua_getn(L, 1);
   n = lua_getn(L, 1);
   if (v == 2)  /* called with only 2 arguments */
   if (v == 2)  /* called with only 2 arguments */
     pos = n+1;
     pos = n+1;
@@ -553,7 +504,7 @@ static int luaB_tinsert (lua_State *L) {
 
 
 static int luaB_tremove (lua_State *L) {
 static int luaB_tremove (lua_State *L) {
   int pos, n;
   int pos, n;
-  luaL_check_rawtype(L, 1, LUA_TTABLE);
+  luaL_check_type(L, 1, LUA_TTABLE);
   n = lua_getn(L, 1);
   n = lua_getn(L, 1);
   pos = luaL_opt_int(L, 2, n);
   pos = luaL_opt_int(L, 2, n);
   if (n <= 0) return 0;  /* table is `empty' */
   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) {
 static int luaB_sort (lua_State *L) {
   int n;
   int n;
-  luaL_check_rawtype(L, 1, LUA_TTABLE);
+  luaL_check_type(L, 1, LUA_TTABLE);
   n = lua_getn(L, 1);
   n = lua_getn(L, 1);
   if (!lua_isnull(L, 2))  /* is there a 2nd argument? */
   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 */
   lua_settop(L, 2);  /* make sure there is two arguments */
   auxsort(L, 1, n);
   auxsort(L, 1, n);
   return 0;
   return 0;
@@ -686,28 +637,19 @@ static const luaL_reg base_funcs[] = {
   {"dofile", luaB_dofile},
   {"dofile", luaB_dofile},
   {"dostring", luaB_dostring},
   {"dostring", luaB_dostring},
   {"error", luaB_error},
   {"error", luaB_error},
+  {"eventtable", luaB_eventtable},
   {"foreach", luaB_foreach},
   {"foreach", luaB_foreach},
   {"foreachi", luaB_foreachi},
   {"foreachi", luaB_foreachi},
   {"gcinfo", luaB_gcinfo},
   {"gcinfo", luaB_gcinfo},
-  {"getglobal", luaB_getglobal},
-  {"gettagmethod", luaB_gettagmethod},
+  {"getglobal", luaB_getglobal},  /* compatibility with 4.0 */
   {"globals", luaB_globals},
   {"globals", luaB_globals},
   {"loadfile", luaB_loadfile},
   {"loadfile", luaB_loadfile},
   {"loadstring", luaB_loadstring},
   {"loadstring", luaB_loadstring},
-  {"newtype", luaB_newtype},
-  {"newtag", luaB_newtype},  /* for compatibility 4.0 */
   {"next", luaB_next},
   {"next", luaB_next},
   {"print", luaB_print},
   {"print", luaB_print},
   {"rawget", luaB_rawget},
   {"rawget", luaB_rawget},
   {"rawset", luaB_rawset},
   {"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},
   {"tonumber", luaB_tonumber},
   {"tostring", luaB_tostring},
   {"tostring", luaB_tostring},
   {"type", luaB_type},
   {"type", luaB_type},

+ 6 - 23
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
 ** Debug Interface
 ** See Copyright Notice in lua.h
 ** 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) {
 static const char *travglobals (lua_State *L, const TObject *o) {
-  Table *g = hvalue(&L->gt);
+  Table *g = hvalue(gt(L));
   int i = sizenode(g);
   int i = sizenode(g);
   while (i--) {
   while (i--) {
     Node *n = node(g, 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 */
   /* try to find a name for given function */
   if ((ar->name = travglobals(L, f)) != NULL)
   if ((ar->name = travglobals(L, f)) != NULL)
     ar->namewhat = "global";
     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) {
 void luaG_typeerror (lua_State *L, StkId o, const char *op) {
   const char *name;
   const char *name;
   const char *kind = getobjname(L, o, &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)
   if (kind)
     luaO_verror(L, "attempt to %.30s %.20s `%.40s' (a %.10s value)",
     luaO_verror(L, "attempt to %.30s %.20s `%.40s' (a %.10s value)",
                 op, kind, name, t);
                 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) {
 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])
   if (t1[2] == t2[2])
     luaO_verror(L, "attempt to compare two %.10s values", t1);
     luaO_verror(L, "attempt to compare two %.10s values", t1);
   else
   else

+ 12 - 9
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
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -43,8 +43,7 @@ void luaD_init (lua_State *L, int stacksize) {
   stacksize += EXTRA_STACK;
   stacksize += EXTRA_STACK;
   L->stack = luaM_newvector(L, stacksize, TObject);
   L->stack = luaM_newvector(L, stacksize, TObject);
   L->stacksize = stacksize;
   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);
   restore_stack_limit(L);
 }
 }
 
 
@@ -143,12 +142,13 @@ void luaD_call (lua_State *L, StkId func) {
   CallInfo ci;
   CallInfo ci;
   if (ttype(func) != LUA_TFUNCTION) {
   if (ttype(func) != LUA_TFUNCTION) {
     /* `func' is not a function; check the `function' tag method */
     /* `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");
       luaG_typeerror(L, func, "call");
     luaD_openstack(L, func);
     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 */
   ci.prev = L->ci;  /* chain new callinfo */
   L->ci = &ci;
   L->ci = &ci;
   ci.base = func+1;
   ci.base = func+1;
@@ -300,9 +300,12 @@ struct lua_longjmp {
 
 
 
 
 static void message (lua_State *L, const char *s) {
 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;
     incr_top;
     setsvalue(top+1, luaS_new(L, s));
     setsvalue(top+1, luaS_new(L, s));
     incr_top;
     incr_top;

+ 1 - 3
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
 ** Auxiliary functions to manipulate prototypes and closures
 ** See Copyright Notice in lua.h
 ** 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 = luaM_new(L, UpVal);  /* not found: create a new one */
   p->v = level;  /* current value lives in the stack */
   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 */
   p->next = *pp;  /* chain it in the proper position */
   *pp = p;
   *pp = p;
   return p;
   return p;
@@ -68,7 +67,6 @@ void luaF_close (lua_State *L, StkId level) {
     p->v = &p->value;  /* now current value lives here */
     p->v = &p->value;  /* now current value lives here */
     L->openupval = p->next;  /* remove from `open' list */
     L->openupval = p->next;  /* remove from `open' list */
     p->next = G(L)->rootupval;  /* chain in `closed' list */
     p->next = G(L)->rootupval;  /* chain in `closed' list */
-    p->mark = 0;  /* now it can be collected */
     G(L)->rootupval = p;
     G(L)->rootupval = p;
   }
   }
 }
 }

+ 61 - 60
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
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 ** 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;}
 #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);
 static void markobject (GCState *st, TObject *o);
 
 
@@ -66,9 +75,9 @@ static void markclosure (GCState *st, Closure *cl) {
       protomark(cl->l.p);
       protomark(cl->l.p);
       for (i=0; i<cl->l.nupvalues; i++) {  /* mark its upvalues */
       for (i=0; i<cl->l.nupvalues; i++) {  /* mark its upvalues */
         UpVal *u = cl->l.upvals[i];
         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));
       strmark(tsvalue(o));
       break;
       break;
     case LUA_TUSERDATA:
     case LUA_TUSERDATA:
-      if (!ismarkedudata(uvalue(o)))
-        switchudatamark(uvalue(o));
+      if (!isudmarked(uvalue(o)))
+        markud(uvalue(o));
       break;
       break;
     case LUA_TFUNCTION:
     case LUA_TFUNCTION:
       markclosure(st, clvalue(o));
       markclosure(st, clvalue(o));
@@ -112,7 +121,6 @@ static void markstacks (lua_State *L, GCState *st) {
   lua_State *L1 = L;
   lua_State *L1 = L;
   do {  /* for each thread */
   do {  /* for each thread */
     StkId o, lim;
     StkId o, lim;
-    markobject(st, &L1->gt);  /* mark table of globals */
     for (o=L1->stack; o<L1->top; o++)
     for (o=L1->stack; o<L1->top; o++)
       markobject(st, o);
       markobject(st, o);
     lim = (L1->stack_last - L1->ci->base > MAXSTACK) ? L1->ci->base+MAXSTACK
     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 */
     h->mark = st->toclear;  /* put in the appropriate list */
     st->toclear = h;
     st->toclear = h;
   }
   }
+  marktable(st, h->eventtable);
   if (!(mode & LUA_WEAK_VALUE)) {
   if (!(mode & LUA_WEAK_VALUE)) {
     i = sizearray(h);
     i = sizearray(h);
     while (i--)
     while (i--)
@@ -172,11 +174,9 @@ static void traversetable (GCState *st, Table *h) {
 
 
 
 
 static void markall (lua_State *L, GCState *st) {
 static void markall (lua_State *L, GCState *st) {
-  marktagmethods(G(L), st);  /* mark tag methods */
   markstacks(L, st); /* mark all stacks */
   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 */
     Table *h = st->tmark;  /* get first table from list */
     st->tmark = h->mark;  /* remove it from list */
     st->tmark = h->mark;  /* remove it from list */
     traversetable(st, h);
     traversetable(st, h);
@@ -189,7 +189,7 @@ static int hasmark (const TObject *o) {
     case LUA_TSTRING:
     case LUA_TSTRING:
       return tsvalue(o)->tsv.marked;
       return tsvalue(o)->tsv.marked;
     case LUA_TUSERDATA:
     case LUA_TUSERDATA:
-      return ismarkedudata(uvalue(o));
+      return isudmarked(uvalue(o));
     case LUA_TTABLE:
     case LUA_TTABLE:
       return ismarked(hvalue(o));
       return ismarked(hvalue(o));
     case LUA_TFUNCTION:
     case LUA_TFUNCTION:
@@ -261,8 +261,9 @@ static void collectupval (lua_State *L) {
   UpVal **v = &G(L)->rootupval;
   UpVal **v = &G(L)->rootupval;
   UpVal *curr;
   UpVal *curr;
   while ((curr = *v) != NULL) {
   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 */
       v = &curr->next;  /* next */
     }
     }
     else {
     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 **p = &G(L)->rootudata;
   Udata *curr;
   Udata *curr;
+  Udata *collected = NULL;
   while ((curr = *p) != NULL) {
   while ((curr = *p) != NULL) {
-    if (ismarkedudata(curr)) {
-      switchudatamark(curr);  /* unmark */
+    if (isudmarked(curr)) {
+      unmarkud(curr);
       p = &curr->uv.next;
       p = &curr->uv.next;
     }
     }
     else {  /* collect */
     else {  /* collect */
-      int tag = curr->uv.tag;
+      const TObject *tm = fasttm(L, curr->uv.eventtable, TM_GC);
       *p = curr->uv.next;
       *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));
         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;
     int oldah = L->allowhooks;
     StkId top = L->top;
     StkId top = L->top;
     L->allowhooks = 0;  /* stop debug hooks during GC tag methods */
     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;
     L->top += 2;
     luaD_call(L, top);
     luaD_call(L, top);
     L->top = top;  /* restore 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);
   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) {
 void luaC_callallgcTM (lua_State *L) {
   if (G(L)->rootudata) {  /* avoid problems with incomplete states */
   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);
   collectstrings(L, all);
   collecttable(L);
   collecttable(L);
   collectproto(L);
   collectproto(L);
   collectupval(L);
   collectupval(L);
   collectclosures(L);
   collectclosures(L);
+  return c;
 }
 }
 
 
 
 
 void luaC_collectgarbage (lua_State *L) {
 void luaC_collectgarbage (lua_State *L) {
+  Udata *c;
   GCState st;
   GCState st;
   st.tmark = NULL;
   st.tmark = NULL;
   st.toclear = NULL;
   st.toclear = NULL;
   markall(L, &st);
   markall(L, &st);
   cleartables(st.toclear);
   cleartables(st.toclear);
-  luaC_collect(L, 0);
+  c = luaC_collect(L, 0);
   checkMbuffer(L);
   checkMbuffer(L);
   G(L)->GCthreshold = 2*G(L)->nblocks;  /* new threshold */
   G(L)->GCthreshold = 2*G(L)->nblocks;  /* new threshold */
-  callgcTMudata(L);
-  callgcTM(L, &luaO_nilobject);
+  callgcTMudata(L, c);
 }
 }
 
 

+ 2 - 2
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
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -16,7 +16,7 @@
 
 
 
 
 void luaC_callallgcTM (lua_State *L);
 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);
 void luaC_collectgarbage (lua_State *L);
 
 
 
 

+ 43 - 15
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
 ** Standard I/O (and system) library
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -61,6 +61,7 @@ static int pushresult (lua_State *L, int i) {
 }
 }
 
 
 
 
+
 /*
 /*
 ** {======================================================
 ** {======================================================
 ** FILE Operations
 ** 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) {
 static FILE *getopthandle (lua_State *L, int inout) {
   FILE *p = (FILE *)(lua_touserdata(L, 1));
   FILE *p = (FILE *)(lua_touserdata(L, 1));
   if (p != NULL) {  /* is it a userdata ? */
   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");
         luaL_argerror(L, 1, "file is closed");
       else
       else
         luaL_argerror(L, 1, "(invalid value)");
         luaL_argerror(L, 1, "(invalid value)");
@@ -84,7 +101,7 @@ static FILE *getopthandle (lua_State *L, int inout) {
   }
   }
   else {  /* try global value */
   else {  /* try global value */
     lua_getglobal(L, filenames[inout]);
     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",
       luaL_verror(L, "global variable `%.10s' is not a valid file handle",
                   filenames[inout]);
                   filenames[inout]);
     p = (FILE *)(lua_touserdata(L, -1));
     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) {
 static void newfile (lua_State *L, FILE *f) {
   lua_newuserdatabox(L, 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;
   int status = 1;
   if (f != stdin && f != stdout && f != stderr) {
   if (f != stdin && f != stdout && f != stderr) {
     lua_settop(L, 1);  /* make sure file is on top */
     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);
     status = (CLOSEFILE(L, f) == 0);
   }
   }
   return pushresult(L, status);
   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");
     luaL_check_stack(L, nargs+LUA_MINSTACK, "too many arguments");
     success = 1;
     success = 1;
     for (n = 1; n<=nargs && success; n++) {
     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);
         size_t l = (size_t)lua_tonumber(L, n);
         success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l);
         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 arg;
   int status = 1;
   int status = 1;
   for (arg=1; arg<=nargs; arg++) {
   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 */
       /* optimization: could be done exactly as for strings */
       status = status &&
       status = status &&
           fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
           fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
@@ -514,7 +535,7 @@ static int io_time (lua_State *L) {
   else {
   else {
     time_t t;
     time_t t;
     struct tm ts;
     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 */
     lua_settop(L, 1);  /* make sure table is at the top */
     ts.tm_sec = getfield(L, "sec", 0);
     ts.tm_sec = getfield(L, "sec", 0);
     ts.tm_min = getfield(L, "min", 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) {
 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);
   luaL_openl(L, iolib);
   /* predefined file handles */
   /* predefined file handles */
   newfilewithname(L, stdin, basicfiles[INFILE]);
   newfilewithname(L, stdin, basicfiles[INFILE]);
@@ -686,9 +717,6 @@ LUALIB_API int lua_iolibopen (lua_State *L) {
   newfilewithname(L, stderr, "_STDERR");
   newfilewithname(L, stderr, "_STDERR");
   resetfile(L, INFILE);
   resetfile(L, INFILE);
   resetfile(L, OUTFILE);
   resetfile(L, OUTFILE);
-  /* close files when collected */
-  lua_pushcfunction(L, file_collect);
-  lua_settagmethod(L, iotag, "gc");
   return 0;
   return 0;
 }
 }
 
 

+ 2 - 3
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
 ** Standard mathematical library
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -220,6 +220,7 @@ static const luaL_reg mathlib[] = {
 {"log10", math_log10},
 {"log10", math_log10},
 {"exp",   math_exp},
 {"exp",   math_exp},
 {"deg",   math_deg},
 {"deg",   math_deg},
+{"pow",   math_pow},
 {"rad",   math_rad},
 {"rad",   math_rad},
 {"random",     math_random},
 {"random",     math_random},
 {"randomseed", math_randomseed}
 {"randomseed", math_randomseed}
@@ -230,8 +231,6 @@ static const luaL_reg mathlib[] = {
 */
 */
 LUALIB_API int lua_mathlibopen (lua_State *L) {
 LUALIB_API int lua_mathlibopen (lua_State *L) {
   luaL_openl(L, mathlib);
   luaL_openl(L, mathlib);
-  lua_pushcfunction(L, math_pow);
-  lua_settagmethod(L, LUA_TNUMBER, "pow");
   lua_pushnumber(L, PI);
   lua_pushnumber(L, PI);
   lua_setglobal(L, "PI");
   lua_setglobal(L, "PI");
   return 0;
   return 0;

+ 5 - 17
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
 ** Type definitions for Lua objects
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -31,15 +31,6 @@
 #define NUM_TAGS	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 {
 typedef union {
   union TString *ts;
   union TString *ts;
   union Udata *u;
   union Udata *u;
@@ -122,17 +113,14 @@ typedef union TString {
 typedef union Udata {
 typedef union Udata {
   union L_Umaxalign dummy;  /* ensures maximum alignment for `local' udata */
   union L_Umaxalign dummy;  /* ensures maximum alignment for `local' udata */
   struct {
   struct {
-    int tag;  /* negative means `marked' (only during GC) */
+    struct Table *eventtable;
     void *value;
     void *value;
-    size_t len;
+    size_t len;  /* least bit reserved for gc mark */
     union Udata *next;  /* chain for list of all udata */
     union Udata *next;  /* chain for list of all udata */
   } uv;
   } uv;
 } Udata;
 } 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 {
 typedef struct UpVal {
   TObject *v;  /* points to stack or to its own value */
   TObject *v;  /* points to stack or to its own value */
-  int mark;
   struct UpVal *next;
   struct UpVal *next;
   TObject value;  /* the value (when closed) */
   TObject value;  /* the value (when closed) */
 } UpVal;
 } UpVal;
@@ -227,12 +214,13 @@ typedef struct Node {
 
 
 
 
 typedef struct Table {
 typedef struct Table {
+  struct Table *eventtable;
   TObject *array;  /* array part */
   TObject *array;  /* array part */
   Node *node;
   Node *node;
-  int htag;
   int sizearray;  /* size of `array' array */
   int sizearray;  /* size of `array' array */
   lu_byte lsizenode;  /* log2 of size of `node' array */
   lu_byte lsizenode;  /* log2 of size of `node' array */
   lu_byte weakmode;
   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 */
   Node *firstfree;  /* this position is free; all positions after it are full */
   struct Table *next;
   struct Table *next;
   struct Table *mark;  /* marked tables (point to itself when not marked) */
   struct Table *mark;  /* marked tables (point to itself when not marked) */

+ 11 - 10
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
 ** Global State
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -40,12 +40,14 @@ static void f_luaopen (lua_State *L, void *ud) {
     so->stacksize += LUA_MINSTACK;
     so->stacksize += LUA_MINSTACK;
   if (so->L != NULL) {  /* shared global state? */
   if (so->L != NULL) {  /* shared global state? */
     L->_G = G(so->L);
     L->_G = G(so->L);
-    L->gt = so->L->gt;  /* share table of globals */
     so->L->next->previous = L;  /* insert L into linked list */
     so->L->next->previous = L;  /* insert L into linked list */
     L->next = so->L->next;
     L->next = so->L->next;
     so->L->next = L;
     so->L->next = L;
     L->previous = so->L;
     L->previous = so->L;
     luaD_init(L, so->stacksize);  /* init stack */
     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 */
   else {  /* create a new global state */
     L->_G = luaM_new(L, 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)->roottable = NULL;
     G(L)->rootudata = NULL;
     G(L)->rootudata = NULL;
     G(L)->rootupval = 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);
     G(L)->nblocks = sizeof(lua_State) + sizeof(global_State);
     luaD_init(L, so->stacksize);  /* init stack */
     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 */
     luaS_resize(L, 4);  /* initial size of string table */
-    luaX_init(L);
     luaT_init(L);
     luaT_init(L);
+    luaX_init(L);
     G(L)->GCthreshold = 4*G(L)->nblocks;
     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)->rootupval == NULL);
     lua_assert(G(L)->roottable == NULL);
     lua_assert(G(L)->roottable == NULL);
     luaS_freeall(L);
     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_freearray(L, G(L)->Mbuffer, G(L)->Mbuffsize, char);
     luaM_freelem(NULL, L->_G);
     luaM_freelem(NULL, L->_G);
   }
   }

+ 24 - 10
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
 ** Global State
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -7,8 +7,10 @@
 #ifndef lstate_h
 #ifndef lstate_h
 #define lstate_h
 #define lstate_h
 
 
-#include "lobject.h"
 #include "lua.h"
 #include "lua.h"
+
+#include "lobject.h"
+#include "ltm.h"
 #include "luadebug.h"
 #include "luadebug.h"
 
 
 
 
@@ -40,7 +42,24 @@
 
 
 
 
 struct lua_longjmp;  /* defined in ldo.c */
 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 {
 typedef struct stringtable {
@@ -57,11 +76,6 @@ typedef struct global_State {
   void *Mbuffer;  /* global buffer */
   void *Mbuffer;  /* global buffer */
   size_t Mbuffsize;  /* size of Mbuffer */
   size_t Mbuffsize;  /* size of Mbuffer */
   stringtable strt;  /* hash table for strings */
   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 GCthreshold;
   lu_mem nblocks;  /* number of `bytes' currently allocated */
   lu_mem nblocks;  /* number of `bytes' currently allocated */
   Proto *rootproto;  /* list of all prototypes */
   Proto *rootproto;  /* list of all prototypes */
@@ -69,6 +83,7 @@ typedef struct global_State {
   Table *roottable;  /* list of all tables */
   Table *roottable;  /* list of all tables */
   Udata *rootudata;   /* list of all userdata */
   Udata *rootudata;   /* list of all userdata */
   UpVal *rootupval;  /* list of closed up values */
   UpVal *rootupval;  /* list of closed up values */
+  TString *tmname[TM_N];  /* array with tag-method names */
 } global_State;
 } global_State;
 
 
 
 
@@ -80,10 +95,9 @@ struct lua_State {
   StkId top;  /* first free slot in the stack */
   StkId top;  /* first free slot in the stack */
   CallInfo *ci;  /* call info for current function */
   CallInfo *ci;  /* call info for current function */
   StkId stack_last;  /* last free slot in the stack */
   StkId stack_last;  /* last free slot in the stack */
-  TObject gt;  /* table for globals */
-  global_State *_G;
   StkId stack;  /* stack base */
   StkId stack;  /* stack base */
   int stacksize;
   int stacksize;
+  global_State *_G;
   lua_Hook callhook;
   lua_Hook callhook;
   lua_Hook linehook;
   lua_Hook linehook;
   int allowhooks;
   int allowhooks;

+ 5 - 3
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)
 ** String table (keeps all strings handled by Lua)
 ** See Copyright Notice in lua.h
 ** 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 *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.len = s;
-  u->uv.tag = 0;
+  u->uv.eventtable = hvalue(defaultet(L));
   u->uv.value = u + 1;
   u->uv.value = u + 1;
   /* chain it on udata list */
   /* chain it on udata list */
   u->uv.next = G(L)->rootudata;
   u->uv.next = G(L)->rootudata;

+ 2 - 2
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
 ** Standard library for string operations and pattern-matching
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -97,7 +97,7 @@ static int str_concat (lua_State *L) {
   size_t lsep;
   size_t lsep;
   const char *sep = luaL_opt_lstr(L, 2, "", &lsep);
   const char *sep = luaL_opt_lstr(L, 2, "", &lsep);
   int n, i;
   int n, i;
-  luaL_check_rawtype(L, 1, LUA_TTABLE);
+  luaL_check_type(L, 1, LUA_TTABLE);
   luaL_buffinit(L, &b);
   luaL_buffinit(L, &b);
   n = lua_getn(L, 1);
   n = lua_getn(L, 1);
   for (i=1; i<=n; i++) {
   for (i=1; i<=n; i++) {

+ 4 - 15
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)
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 ** 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 *luaH_new (lua_State *L, int narray, int lnhash) {
   Table *t = luaM_new(L, Table);
   Table *t = luaM_new(L, Table);
-  t->htag = TagDefault;
+  t->eventtable = hvalue(defaultet(L));
   t->next = G(L)->roottable;
   t->next = G(L)->roottable;
   G(L)->roottable = t;
   G(L)->roottable = t;
   t->mark = t;
   t->mark = t;
   t->weakmode = 0;
   t->weakmode = 0;
+  t->flags = ~0;
   /* temporary values (kept only if some malloc fails) */
   /* temporary values (kept only if some malloc fails) */
   t->array = NULL;
   t->array = NULL;
   t->sizearray = 0;
   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");
     if (ttype(key) == LUA_TNIL) luaD_error(L, "table index is nil");
     newkey(L, t, key, val);
     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;
 }
 }
 
 
 
 

+ 1 - 2
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)
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -20,7 +20,6 @@
 const TObject *luaH_getnum (Table *t, int key);
 const TObject *luaH_getnum (Table *t, int key);
 void luaH_setnum (lua_State *L, Table *t, int key, const TObject *val);
 void luaH_setnum (lua_State *L, Table *t, int key, const TObject *val);
 const TObject *luaH_getstr (Table *t, TString *key);
 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);
 const TObject *luaH_get (Table *t, const TObject *key);
 void luaH_set (lua_State *L, Table *t, const TObject *key, const TObject *val);
 void luaH_set (lua_State *L, Table *t, const TObject *key, const TObject *val);
 Table *luaH_new (lua_State *L, int narray, int lnhash);
 Table *luaH_new (lua_State *L, int narray, int lnhash);

+ 23 - 38
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
 ** Internal Module for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -240,13 +240,13 @@ static int mem_query (lua_State *L) {
 
 
 static int hash_query (lua_State *L) {
 static int hash_query (lua_State *L) {
   if (lua_isnull(L, 2)) {
   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);
     lua_pushnumber(L, tsvalue(luaA_index(L, 1))->tsv.hash);
   }
   }
   else {
   else {
     TObject *o = luaA_index(L, 1);
     TObject *o = luaA_index(L, 1);
     Table *t;
     Table *t;
-    luaL_check_rawtype(L, 2, LUA_TTABLE);
+    luaL_check_type(L, 2, LUA_TTABLE);
     t = hvalue(luaA_index(L, 2));
     t = hvalue(luaA_index(L, 2));
     lua_pushnumber(L, luaH_mainposition(t, o) - t->node);
     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) {
 static int table_query (lua_State *L) {
   const Table *t;
   const Table *t;
   int i = luaL_opt_int(L, 2, -1);
   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));
   t = hvalue(luaA_index(L, 1));
   if (i == -1) {
   if (i == -1) {
     lua_pushnumber(L, t->sizearray);
     lua_pushnumber(L, t->sizearray);
@@ -333,6 +333,18 @@ static int unref (lua_State *L) {
   return 0;
   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) {
 static int newuserdata (lua_State *L) {
   size_t size = luaL_check_int(L, 1);
   size_t size = luaL_check_int(L, 1);
   char *p = cast(char *, lua_newuserdata(L, size));
   char *p = cast(char *, lua_newuserdata(L, size));
@@ -345,24 +357,13 @@ static int newuserdatabox (lua_State *L) {
   return 1;
   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) {
 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)));
   lua_pushnumber(L, cast(int, lua_touserdata(L, 1)));
   return 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) {
 static int doonnewstack (lua_State *L) {
   lua_State *L1 = lua_newthread(L, luaL_check_int(L, 1));
   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) {
 static int log2_aux (lua_State *L) {
   lua_pushnumber(L, luaO_log2(luaL_check_int(L, 1)));
   lua_pushnumber(L, luaO_log2(luaL_check_int(L, 1)));
@@ -614,18 +605,14 @@ static int testC (lua_State *L) {
     else if EQ("dostring") {
     else if EQ("dostring") {
       lua_dostring(L, luaL_check_string(L, getnum));
       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") {
     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);
     else luaL_verror(L, "unknown instruction %.30s", buff);
   }
   }
@@ -651,16 +638,14 @@ static const struct luaL_reg tests_funcs[] = {
   {"unref", unref},
   {"unref", unref},
   {"d2s", d2s},
   {"d2s", d2s},
   {"s2d", s2d},
   {"s2d", s2d},
+  {"eventtable", eventtable},
   {"newuserdata", newuserdata},
   {"newuserdata", newuserdata},
   {"newuserdatabox", newuserdatabox},
   {"newuserdatabox", newuserdatabox},
-  {"settag", settag},
   {"udataval", udataval},
   {"udataval", udataval},
-  {"newtag", newtag},
   {"doonnewstack", doonnewstack},
   {"doonnewstack", doonnewstack},
   {"newstate", newstate},
   {"newstate", newstate},
   {"closestate", closestate},
   {"closestate", closestate},
   {"doremote", doremote},
   {"doremote", doremote},
-  {"settagmethod", settagmethod},
   {"log2", log2_aux},
   {"log2", log2_aux},
   {"totalmem", mem_query}
   {"totalmem", mem_query}
 };
 };

+ 24 - 141
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
 ** Tag methods
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -10,8 +10,6 @@
 
 
 #include "lua.h"
 #include "lua.h"
 
 
-#include "ldo.h"
-#include "lmem.h"
 #include "lobject.h"
 #include "lobject.h"
 #include "lstate.h"
 #include "lstate.h"
 #include "lstring.h"
 #include "lstring.h"
@@ -19,161 +17,46 @@
 #include "ltm.h"
 #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) {
 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;
   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:
     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:
     default:
-      luaD_error(L, "tag method must be a function (or nil)");
+      return NULL;
   }
   }
-  L->top--;
-  lua_unlock(L);
 }
 }
 
 

+ 8 - 41
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
 ** Tag methods
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -9,7 +9,6 @@
 
 
 
 
 #include "lobject.h"
 #include "lobject.h"
-#include "lstate.h"
 
 
 /*
 /*
 * WARNING: if you change the order of this enumeration,
 * WARNING: if you change the order of this enumeration,
@@ -19,8 +18,7 @@ typedef enum {
   TM_GETTABLE = 0,
   TM_GETTABLE = 0,
   TM_SETTABLE,
   TM_SETTABLE,
   TM_INDEX,
   TM_INDEX,
-  TM_GETGLOBAL,
-  TM_SETGLOBAL,
+  TM_GC,
   TM_ADD,
   TM_ADD,
   TM_SUB,
   TM_SUB,
   TM_MUL,
   TM_MUL,
@@ -29,51 +27,20 @@ typedef enum {
   TM_UNM,
   TM_UNM,
   TM_LT,
   TM_LT,
   TM_CONCAT,
   TM_CONCAT,
-  TM_GC,
-  TM_FUNCTION,
+  TM_CALL,
   TM_N		/* number of elements in the enum */
   TM_N		/* number of elements in the enum */
 } TMS;
 } 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);
 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
 #endif

+ 12 - 24
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
 ** Lua - An Extensible Extension Language
 ** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
 ** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
 ** e-mail: [email protected]
 ** e-mail: [email protected]
@@ -55,15 +55,11 @@ typedef struct lua_State lua_State;
 typedef int (*lua_CFunction) (lua_State *L);
 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_TUSERDATA	0
 #define LUA_TNIL	1
 #define LUA_TNIL	1
@@ -120,12 +116,11 @@ LUA_API int   lua_stackspace (lua_State *L);
 ** access functions (stack -> C)
 ** 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_isnumber (lua_State *L, int index);
 LUA_API int             lua_isstring (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_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_equal (lua_State *L, int index1, int index2);
 LUA_API int            lua_lessthan (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_gettable (lua_State *L, int index);
 LUA_API void  lua_rawget (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_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_newtable (lua_State *L);
 LUA_API void  lua_getweakregistry (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_rawset (lua_State *L, int index);
 LUA_API void  lua_rawseti (lua_State *L, int index, int n);
 LUA_API void  lua_rawseti (lua_State *L, int index, int n);
 LUA_API void  lua_setglobals (lua_State *L);
 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
 ** 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);
 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_register(L,n,f)	(lua_pushcfunction(L, f), lua_setglobal(L, n))
 #define lua_pushcfunction(L,f)	lua_pushcclosure(L, f, 0)
 #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, \
 #define lua_pushliteral(L, s)	lua_pushlstring(L, "" s, \
                                                 (sizeof(s)/sizeof(char))-1)
                                                 (sizeof(s)/sizeof(char))-1)
@@ -245,8 +235,6 @@ LUA_API int   lua_getweakmode (lua_State *L, int index);
 /*
 /*
 ** compatibility macros and functions
 ** 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);
 LUA_API void lua_pushupvalues (lua_State *L);
 
 

+ 58 - 79
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
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 ** 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) */
 /* maximum stack used by a call to a tag method (func + args) */
 #define MAXSTACK_TM	4
 #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;
   StkId base = L->top;
-  lua_assert(strlen(fmt)+1 <= MAXSTACK_TM);
   luaD_checkstack(L, 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++;
     L->top++;
   }
   }
   luaD_call(L, base);
   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 */
   L->top = base;  /* restore top */
 }
 }
 
 
 
 
+
 /*
 /*
 ** Function to index a table.
 ** Function to index a table.
 ** Receives the table at `t' and the key at the `key'.
 ** Receives the table at `t' and the key at the `key'.
 ** leaves the result at `res'.
 ** leaves the result at `res'.
 */
 */
 void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId 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? */
   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 */
       const TObject *h = luaH_get(hvalue(t), key);  /* do a primitive get */
       /* result is no nil or there is no `index' tag method? */
       /* result is no nil or there is no `index' tag method? */
       if (ttype(h) != LUA_TNIL ||  /* no nil? */
       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 */
         setobj(res, h);  /* default get */
         return;
         return;
       }
       }
     }
     }
     /* else will call the tag method */
     /* else will call the tag method */
   } else {  /* not a table; try a `gettable' 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");
       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'.
 ** Receives table at `t', key at `key' and value at `val'.
 */
 */
 void luaV_settable (lua_State *L, StkId t, TObject *key, StkId 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? */
   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 */
       luaH_set(L, hvalue(t), key, val);  /* do a primitive set */
       return;
       return;
     }
     }
     /* else will call the tag method */
     /* else will call the tag method */
   } else {  /* not a table; try a `settable' 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");
       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,
 static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2,
                        TObject *res, TMS event) {
                        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) {
   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) {
     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;
   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) {
 static void luaV_pack (lua_State *L, StkId firstelem) {
   int i;
   int i;
   Table *htab = luaH_new(L, 0, 0);
   Table *htab = luaH_new(L, 0, 0);
-  TObject n;
+  TObject n, nname;
   for (i=0; firstelem+i<L->top; i++)
   for (i=0; firstelem+i<L->top; i++)
     luaH_setnum(L, htab, i+1, firstelem+i);
     luaH_setnum(L, htab, i+1, firstelem+i);
   /* store counter in field `n' */
   /* store counter in field `n' */
   setnvalue(&n, i);
   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 */
   L->top = firstelem;  /* remove elements from the stack */
   sethvalue(L->top, htab);
   sethvalue(L->top, htab);
   incr_top;
   incr_top;
@@ -395,7 +374,7 @@ StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) {
       }
       }
       case OP_GETGLOBAL: {
       case OP_GETGLOBAL: {
         lua_assert(ttype(KBc(i)) == LUA_TSTRING);
         lua_assert(ttype(KBc(i)) == LUA_TSTRING);
-        luaV_getglobal(L, tsvalue(KBc(i)), ra);
+        luaV_gettable(L, gt(L), KBc(i), ra);
         break;
         break;
       }
       }
       case OP_GETTABLE: {
       case OP_GETTABLE: {
@@ -404,7 +383,7 @@ StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) {
       }
       }
       case OP_SETGLOBAL: {
       case OP_SETGLOBAL: {
         lua_assert(ttype(KBc(i)) == LUA_TSTRING);
         lua_assert(ttype(KBc(i)) == LUA_TSTRING);
-        luaV_setglobal(L, tsvalue(KBc(i)), ra);
+        luaV_settable(L, gt(L), KBc(i), ra);
         break;
         break;
       }
       }
       case OP_SETUPVAL: {
       case OP_SETUPVAL: {

+ 1 - 3
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
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 ** 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);
 int luaV_tostring (lua_State *L, TObject *obj);
 void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res);
 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_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);
 StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base);
 int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r);
 int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r);
 void luaV_strconc (lua_State *L, int total, StkId top);
 void luaV_strconc (lua_State *L, int total, StkId top);