diff --git a/lauxlib.c b/lauxlib.c
index 9ecec884..9f39b46b 100644
--- a/lauxlib.c
+++ b/lauxlib.c
@@ -1,5 +1,5 @@
 /*
-** $Id: lauxlib.c,v 1.91 2002/12/04 17:38:31 roberto Exp roberto $
+** $Id: lauxlib.c,v 1.92 2003/01/23 11:34:18 roberto Exp roberto $
 ** Auxiliary functions for building Lua libraries
 ** See Copyright Notice in lua.h
 */
@@ -23,6 +23,13 @@
 #include "lauxlib.h"
 
 
+/* number of prereserved references (for internal use) */
+#define RESERVED_REFS	1
+
+/* reserved reference for array sizes */
+#define ARRAYSIZE_REF	1
+
+
 /*
 ** {======================================================
 ** Error-report functions
@@ -195,6 +202,78 @@ LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
 
 
 
+/*
+** {======================================================
+** getn-setn: size for arrays
+** =======================================================
+*/
+
+static int checkint (lua_State *L, int topop) {
+  int n = (int)lua_tonumber(L, -1);
+  if (n == 0 && !lua_isnumber(L, -1)) n = -1;
+  lua_pop(L, topop);
+  return n;
+}
+
+
+static void getsizes (lua_State *L) {
+  lua_rawgeti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF);
+  if (lua_isnil(L, -1)) {  /* no `size' table? */
+    lua_newtable(L);  /* create it */
+    lua_pushvalue(L, -1);  /* `size' will be its own metatable */
+    lua_setmetatable(L, -2);
+    lua_pushliteral(L, "__mode");
+    lua_pushliteral(L, "k");
+    lua_rawset(L, -3);  /* metatable(N).__mode = "k" */
+    lua_pushvalue(L, -1);
+    lua_rawseti(L, LUA_REGISTRYINDEX, ARRAYSIZE_REF);  /* store in register */
+  }
+}
+
+
+void luaL_setn (lua_State *L, int t, int n) {
+  lua_pushliteral(L, "n");
+  lua_rawget(L, t);
+  if (checkint(L, 1) >= 0) {  /* is there a numeric field `n'? */
+    lua_pushliteral(L, "n");  /* use it */
+    lua_pushnumber(L, n);
+    lua_rawset(L, t);
+  }
+  else {  /* use `sizes' */
+    getsizes(L);
+    lua_pushvalue(L, t);
+    lua_pushnumber(L, n);
+    lua_rawset(L, -3);  /* sizes[t] = n */
+    lua_pop(L, 1);  /* remove `sizes' */
+  }
+}
+
+
+int luaL_getn (lua_State *L, int t) {
+  int n;
+  lua_pushliteral(L, "n");  /* try t.n */
+  lua_rawget(L, t);
+  if ((n = checkint(L, 1)) >= 0) return n;
+  getsizes(L);  /* else try sizes[t] */
+  lua_pushvalue(L, t);
+  lua_rawget(L, -2);
+  if ((n = checkint(L, 2)) >= 0) return n;
+  else {  /* must count elements */
+    for (n = 1; ; n++) {
+      lua_rawgeti(L, t, n);
+      if (lua_isnil(L, -1)) break;
+      lua_pop(L, 1);
+    }
+    lua_pop(L, 1);
+    luaL_setn(L, t, n - 1);
+    return n - 1;
+  }
+}
+
+/* }====================================================== */
+
+
+
 /*
 ** {======================================================
 ** Generic Buffer manipulation
@@ -308,8 +387,10 @@ LUALIB_API int luaL_ref (lua_State *L, int t) {
     lua_pushliteral(L, "n");
     lua_pushvalue(L, -1);
     lua_rawget(L, t);  /* get t.n */
-    ref = (int)lua_tonumber(L, -1) + 1;  /* ref = t.n + 1 */
+    ref = (int)lua_tonumber(L, -1);  /* ref = t.n */
     lua_pop(L, 1);  /* pop t.n */
+    if (ref == 0) ref = RESERVED_REFS;  /* skip reserved references */
+    ref++;  /* create new reference */
     lua_pushnumber(L, ref);
     lua_rawset(L, t);  /* t.n = t.n + 1 */
   }
diff --git a/lauxlib.h b/lauxlib.h
index 25d8499c..fb2b0ab6 100644
--- a/lauxlib.h
+++ b/lauxlib.h
@@ -1,5 +1,5 @@
 /*
-** $Id: lauxlib.h,v 1.55 2002/11/14 15:41:38 roberto Exp roberto $
+** $Id: lauxlib.h,v 1.56 2003/01/17 15:28:09 roberto Exp roberto $
 ** Auxiliary functions for building Lua libraries
 ** See Copyright Notice in lua.h
 */
@@ -51,6 +51,9 @@ LUALIB_API int luaL_findstring (const char *st, const char *const lst[]);
 LUALIB_API int luaL_ref (lua_State *L, int t);
 LUALIB_API void luaL_unref (lua_State *L, int t, int ref);
 
+LUALIB_API int luaL_getn (lua_State *L, int t);
+LUALIB_API void luaL_setn (lua_State *L, int t, int n);
+
 LUALIB_API int luaL_loadfile (lua_State *L, const char *filename);
 LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t sz,
                                 const char *name);
diff --git a/ltablib.c b/ltablib.c
index 504081bc..c0e773aa 100644
--- a/ltablib.c
+++ b/ltablib.c
@@ -1,5 +1,5 @@
 /*
-** $Id: ltablib.c,v 1.17 2002/12/04 17:38:31 roberto Exp roberto $
+** $Id: ltablib.c,v 1.18 2002/12/20 10:26:33 roberto Exp roberto $
 ** Library for Table Manipulation
 ** See Copyright Notice in lua.h
 */
@@ -15,52 +15,7 @@
 #include "lualib.h"
 
 
-
-static int checkint (lua_State *L) {
-  int n = (int)lua_tonumber(L, -1);
-  if (n == 0 && !lua_isnumber(L, -1)) n = -1;
-  lua_pop(L, 1);
-  return n;
-}
-
-
-static void aux_setn (lua_State *L, int t, int n) {
-  lua_pushliteral(L, "n");
-  lua_rawget(L, t);
-  if (checkint(L) >= 0) {
-    lua_pushliteral(L, "n");  /* use it */
-    lua_pushnumber(L, n);
-    lua_rawset(L, t);
-  }
-  else {  /* use N */
-    lua_pushvalue(L, t);
-    lua_pushnumber(L, n);
-    lua_rawset(L, lua_upvalueindex(1));  /* N[t] = n */
-  }
-}
-
-
-static int aux_getn (lua_State *L, int t) {
-  int n;
-  luaL_checktype(L, t, LUA_TTABLE);
-  lua_pushliteral(L, "n");  /* try t.n */
-  lua_rawget(L, t);
-  if ((n = checkint(L)) >= 0) return n;
-  lua_pushvalue(L, t);  /* try N[t] */
-  lua_rawget(L, lua_upvalueindex(1));
-  if ((n = checkint(L)) >= 0) return n;
-  else {  /* must count elements */
-    n = 0;
-    for (;;) {
-      lua_rawgeti(L, t, ++n);
-      if (lua_isnil(L, -1)) break;
-      lua_pop(L, 1);
-    }
-    lua_pop(L, 1);
-    aux_setn(L, t, n - 1);
-    return n - 1;
-  }
-}
+#define aux_getn(L,n)	(luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))
 
 
 static int luaB_foreachi (lua_State *L) {
@@ -106,7 +61,7 @@ static int luaB_getn (lua_State *L) {
 
 static int luaB_setn (lua_State *L) {
   luaL_checktype(L, 1, LUA_TTABLE);
-  aux_setn(L, 1, luaL_checkint(L, 2));
+  luaL_setn(L, 1, luaL_checkint(L, 2));
   return 0;
 }
 
@@ -122,7 +77,7 @@ static int luaB_tinsert (lua_State *L) {
     if (pos > n) n = pos;  /* `grow' array if necessary */
     v = 3;  /* function may be called with more than 3 args */
   }
-  aux_setn(L, 1, n);  /* new size */
+  luaL_setn(L, 1, n);  /* new size */
   while (--n >= pos) {  /* move up elements */
     lua_rawgeti(L, 1, n);
     lua_rawseti(L, 1, n+1);  /* t[n+1] = t[n] */
@@ -137,7 +92,7 @@ static int luaB_tremove (lua_State *L) {
   int n = aux_getn(L, 1);
   int pos = luaL_optint(L, 2, n);
   if (n <= 0) return 0;  /* table is `empty' */
-  aux_setn(L, 1, n-1);  /* t.n = n-1 */
+  luaL_setn(L, 1, n-1);  /* t.n = n-1 */
   lua_rawgeti(L, 1, pos);  /* result = t[pos] */
   for ( ;pos<n; pos++) {
     lua_rawgeti(L, 1, pos+1);
@@ -156,7 +111,7 @@ static int str_concat (lua_State *L) {
   int i = luaL_optint(L, 3, 1);
   int n = luaL_optint(L, 4, 0);
   luaL_checktype(L, 1, LUA_TTABLE);
-  if (n == 0) n = aux_getn(L, 1);
+  if (n == 0) n = luaL_getn(L, 1);
   luaL_buffinit(L, &b);
   for (; i <= n; i++) {
     lua_rawgeti(L, 1, i);
@@ -289,13 +244,7 @@ static const luaL_reg tab_funcs[] = {
 
 
 LUALIB_API int lua_tablibopen (lua_State *L) {
-  lua_newtable(L);  /* create N (table to store num. elements in tables) */
-  lua_pushvalue(L, -1);  /* `N' will be its own metatable */
-  lua_setmetatable(L, -2);
-  lua_pushliteral(L, "__mode");
-  lua_pushliteral(L, "k");
-  lua_rawset(L, -3);  /* metatable(N).__mode = "k" */
-  luaL_openlib(L, LUA_TABLIBNAME, tab_funcs, 1);
+  luaL_openlib(L, LUA_TABLIBNAME, tab_funcs, 0);
   return 1;
 }