Browse Source

first version for new API

Roberto Ierusalimschy 25 năm trước cách đây
mục cha
commit
9fdf73bc9a
24 tập tin đã thay đổi với 1205 bổ sung1359 xóa
  1. 211 221
      lapi.c
  2. 2 3
      lapi.h
  3. 29 39
      lauxlib.c
  4. 5 7
      lauxlib.h
  5. 187 150
      lbuiltin.c
  6. 29 29
      lbuiltin.h
  7. 49 55
      ldblib.c
  8. 21 19
      ldebug.c
  9. 35 52
      ldo.c
  10. 1 2
      ldo.h
  11. 39 3
      lgc.c
  12. 109 87
      liolib.c
  13. 1 7
      llimits.h
  14. 77 45
      lmathlib.c
  15. 0 118
      lref.c
  16. 0 27
      lref.h
  17. 1 7
      lstate.c
  18. 17 18
      lstate.h
  19. 57 47
      lstrlib.c
  20. 213 200
      ltests.c
  21. 38 36
      lua.c
  22. 78 173
      lua.h
  23. 4 12
      luadebug.h
  24. 2 2
      lundump.c

+ 211 - 221
lapi.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 1.86 2000/08/09 19:16:57 roberto Exp roberto $
+** $Id: lapi.c,v 1.87 2000/08/14 19:10:14 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -16,7 +16,6 @@
 #include "lgc.h"
 #include "lmem.h"
 #include "lobject.h"
-#include "lref.h"
 #include "lstate.h"
 #include "lstring.h"
 #include "ltable.h"
@@ -29,246 +28,148 @@ const char lua_ident[] = "$Lua: " LUA_VERSION " " LUA_COPYRIGHT " $\n"
 
 
 
-void luaA_checkCargs (lua_State *L, int nargs) {
-  if (nargs > L->top-L->Cstack.base)
-    luaL_verror(L, "Lua API error - "
-                   "expected at least %d arguments in C2lua stack", nargs);
-}
-
+#define Index(L,i)	((i) >= 0 ? (L->Cbase+((i)-1)) : (L->top+(i)))
 
-lua_Object luaA_putluaObject (lua_State *L, const TObject *o) {
-  luaD_openstack(L, L->Cstack.base);
-  *L->Cstack.base++ = *o;
-  return L->Cstack.base-1;
-}
+#define api_incr_top(L)	(++L->top)
 
 
-static void top2LC (lua_State *L, int n) {
-  /* Put the `n' elements on the top as the Lua2C contents */
-  L->Cstack.base = L->top;  /* new base */
-  L->Cstack.lua2C = L->Cstack.base-n;  /* position of the new results */
-  L->Cstack.num = n;  /* number of results */
-}
 
 
-lua_Object lua_pop (lua_State *L) {
-  luaA_checkCargs(L, 1);
-  if (L->Cstack.base != L->top-1) {
-    luaD_openstack(L, L->Cstack.base);
-    *L->Cstack.base = *(--L->top);
-  }
-  return L->Cstack.base++;
+TObject *luaA_index (lua_State *L, int index) {
+  return Index(L, index);
 }
 
 
-void lua_pushglobals (lua_State *L) {
-  hvalue(L->top) = L->gt;
-  ttype(L->top) = TAG_TABLE;
+void luaA_pushobject (lua_State *L, const TObject *o) {
+  *L->top = *o;
   incr_top;
 }
 
 
-void lua_setglobals (lua_State *L, lua_Object newtable) {
-  if (lua_type(L, newtable)[0] != 't')  /* type == "table"? */
-    lua_error(L, "Lua API error - invalid value for global table");
-  L->gt = hvalue(newtable);
-}
-
 
 /*
-** Get a parameter, returning the object handle or LUA_NOOBJECT on error.
-** `number' must be 1 to get the first parameter.
+** basic stack manipulation
 */
-lua_Object lua_lua2C (lua_State *L, int number) {
-  if (number <= 0 || number > L->Cstack.num) return LUA_NOOBJECT;
-  return L->Cstack.lua2C+number-1;
-}
 
 
-int lua_callfunction (lua_State *L, lua_Object function) {
-  if (function == LUA_NOOBJECT)
-    return 1;
-  else {
-    luaD_openstack(L, L->Cstack.base);
-    *L->Cstack.base = *function;
-    return luaD_protectedrun(L);
-  }
+int lua_gettop (lua_State *L) {
+  return (L->top - L->Cbase);
 }
 
 
-lua_Object lua_gettagmethod (lua_State *L, int tag, const char *event) {
-  return luaA_putluaObject(L, luaT_gettagmethod(L, tag, event));
+void lua_settop (lua_State *L, int index) {
+  if (index >= 0)
+    luaD_adjusttop(L, L->Cbase, index);
+  else
+    L->top += index;  /* index is negative */
 }
 
 
-lua_Object lua_settagmethod (lua_State *L, int tag, const char *event) {
-  TObject *method;
-  luaA_checkCargs(L, 1);
-  method = L->top-1;
-  if ((ttype(method) != TAG_NIL) && (*lua_type(L, method) != 'f'))
-    lua_error(L, "Lua API error - tag method must be a function or nil");
-  luaT_settagmethod(L, tag, event, method);
-  return lua_pop(L);
+void lua_pushobject (lua_State *L, int index) {
+  *L->top = *Index(L, index);
+  api_incr_top(L);
 }
 
 
-lua_Object lua_gettable (lua_State *L) {
-  luaA_checkCargs(L, 2);
-  luaV_gettable(L, L->top--);
-  return lua_pop(L);
-}
-
 
-lua_Object lua_rawget (lua_State *L) {
-  lua_Object res;
-  luaA_checkCargs(L, 2);
-  if (ttype(L->top-2) != TAG_TABLE)
-    lua_error(L, "indexed expression not a table");
-  res = luaA_putluaObject(L, luaH_get(L, hvalue(L->top-2), L->top-1));
-  L->top -= 2;
-  return res;
-}
+/*
+** access functions (stack -> C)
+*/
 
 
-void lua_settable (lua_State *L) {
-  StkId top;
-  luaA_checkCargs(L, 3);
-  top = L->top;
-  luaV_settable(L, top-3, top);
-  L->top = top-3;  /* pop table, index, and value */
-}
+#define btest(L,i,value,default)	{ \
+  StkId o; \
+  if ((i) >= 0) { \
+    o = L->Cbase+((i)-1); \
+    if (o >= L->top) return (default); \
+  } \
+  else o = L->top+(i); \
+  return (value); }
 
 
-void lua_rawset (lua_State *L) {
-  luaA_checkCargs(L, 3);
-  if (ttype(L->top-3) != TAG_TABLE)
-    lua_error(L, "indexed expression not a table");
-  *luaH_set(L, hvalue(L->top-3), L->top-2) = *(L->top-1);
-  L->top -= 3;
-}
+#define access(L,i,test,default,value)	{ \
+  StkId o; \
+  if ((i) >= 0) { \
+    o = L->Cbase+((i)-1); \
+    if (o >= L->top) return (default); \
+  } \
+  else o = L->top+(i); \
+  return ((test) ? (value) : (default)); }
 
 
-lua_Object lua_createtable (lua_State *L) {
-  TObject o;
-  luaC_checkGC(L);
-  hvalue(&o) = luaH_new(L, 0);
-  ttype(&o) = TAG_TABLE;
-  return luaA_putluaObject(L, &o);
+const char *lua_type (lua_State *L, int index) {
+  btest(L, index, luaO_typename(o), "NO VALUE");
 }
 
-
-lua_Object lua_getglobal (lua_State *L, const char *name) {
-  luaV_getglobal(L, luaS_new(L, name), L->top++);
-  return lua_pop(L);
+int lua_iscfunction (lua_State *L, int index) {
+  btest(L, index, (ttype(o) == TAG_CCLOSURE), 0);
 }
 
-
-void lua_setglobal (lua_State *L, const char *name) {
-  luaA_checkCargs(L, 1);
-  luaV_setglobal(L, luaS_new(L, name), L->top--);
+int lua_isnumber (lua_State *L, int index) {
+  btest(L, index, (tonumber(Index(L, index)) == 0), 0);
 }
 
-
-const char *lua_type (lua_State *L, lua_Object o) {
-  UNUSED(L);
-  return (o == LUA_NOOBJECT) ? "NOOBJECT" : luaO_typename(o);
+int lua_tag (lua_State *L, int index) {
+  btest(L, index, 
+   ((ttype(o) == TAG_USERDATA) ? tsvalue(o)->u.d.tag : luaT_effectivetag(L, o)),
+   -1);
 }
 
-int lua_isnil (lua_State *L, lua_Object o) {
-  UNUSED(L);
-  return (o != LUA_NOOBJECT) && (ttype(o) == TAG_NIL);
+int lua_equal(lua_State *L, int index1, int index2) {
+  return luaO_equalObj(Index(L, index1), Index(L, index2));
 }
 
-int lua_istable (lua_State *L, lua_Object o) {
-  UNUSED(L);
-  return (o != LUA_NOOBJECT) && (ttype(o) == TAG_TABLE);
-}
 
-int lua_isuserdata (lua_State *L, lua_Object o) {
-  UNUSED(L);
-  return (o != LUA_NOOBJECT) && (ttype(o) == TAG_USERDATA);
-}
 
-int lua_iscfunction (lua_State *L, lua_Object o) {
-  UNUSED(L);
-  return (o != LUA_NOOBJECT) && (ttype(o) == TAG_CCLOSURE);
+double lua_tonumber (lua_State *L, int index) {
+  access(L, index, (tonumber(o) == 0), 0.0, nvalue(o));
 }
 
-int lua_isnumber (lua_State *L, lua_Object o) {
-  UNUSED(L);
-  return (o != LUA_NOOBJECT) && (tonumber(o) == 0);
+const char *lua_tostring (lua_State *L, int index) {
+  luaC_checkGC(L);  /* `tostring' may create a new string */
+  access(L, index, (tostring(L, o) == 0), NULL, svalue(o));
 }
 
-int lua_isstring (lua_State *L, lua_Object o) {
-  UNUSED(L);
-  return (o != LUA_NOOBJECT && (ttype(o) == TAG_STRING ||
-                                ttype(o) == TAG_NUMBER));
+size_t lua_strlen (lua_State *L, int index) {
+  access(L, index, (tostring(L, o) == 0), 0, tsvalue(o)->u.s.len);
 }
 
-int lua_isfunction (lua_State *L, lua_Object o) {
-  return *lua_type(L, o) == 'f';
+lua_CFunction lua_tocfunction (lua_State *L, int index) {
+  access(L, index, (ttype(o) == TAG_CCLOSURE), NULL, clvalue(o)->f.c);
 }
 
-int lua_equal(lua_State *L, lua_Object o1, lua_Object o2) {
-  UNUSED(L);
-  if (o1 == LUA_NOOBJECT || o2 == LUA_NOOBJECT)
-    return (o1 == o2);
-  else return luaO_equalObj(o1, o2);
+void *lua_touserdata (lua_State *L, int index) {
+  access(L, index, (ttype(o) == TAG_USERDATA), NULL, tsvalue(o)->u.d.value);
 }
 
 
-double lua_getnumber (lua_State *L, lua_Object obj) {
-  UNUSED(L);
-  if (obj == LUA_NOOBJECT  || tonumber(obj))
-     return 0.0;
-  else return (nvalue(obj));
-}
 
-const char *lua_getstring (lua_State *L, lua_Object obj) {
-  luaC_checkGC(L);  /* `tostring' may create a new string */
-  if (obj == LUA_NOOBJECT || tostring(L, obj))
-    return NULL;
-  else return (svalue(obj));
-}
-
-size_t lua_strlen (lua_State *L, lua_Object obj) {
-  if (obj == LUA_NOOBJECT || tostring(L, obj))
-    return 0L;
-  else return (tsvalue(obj)->u.s.len);
-}
-
-void *lua_getuserdata (lua_State *L, lua_Object obj) {
-  UNUSED(L);
-  if (obj == LUA_NOOBJECT || ttype(obj) != TAG_USERDATA)
-    return NULL;
-  else return tsvalue(obj)->u.d.value;
-}
-
-lua_CFunction lua_getcfunction (lua_State *L, lua_Object obj) {
-  if (!lua_iscfunction(L, obj))
-    return NULL;
-  else return clvalue(obj)->f.c;
-}
+/*
+** push functions (C -> stack)
+*/
 
 
 void lua_pushnil (lua_State *L) {
   ttype(L->top) = TAG_NIL;
-  incr_top;
+  api_incr_top(L);
 }
 
+
 void lua_pushnumber (lua_State *L, double n) {
   ttype(L->top) = TAG_NUMBER;
   nvalue(L->top) = n;
-  incr_top;
+  api_incr_top(L);
 }
 
+
 void lua_pushlstring (lua_State *L, const char *s, size_t len) {
+  luaC_checkGC(L);
   tsvalue(L->top) = luaS_newlstr(L, s, len);
   ttype(L->top) = TAG_STRING;
-  incr_top;
-  luaC_checkGC(L);
+  api_incr_top(L);
 }
 
+
 void lua_pushstring (lua_State *L, const char *s) {
   if (s == NULL)
     lua_pushnil(L);
@@ -276,48 +177,154 @@ void lua_pushstring (lua_State *L, const char *s) {
     lua_pushlstring(L, s, strlen(s));
 }
 
+
 void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
-  if (fn == NULL)
-    lua_error(L, "Lua API error - attempt to push a NULL Cfunction");
-  luaA_checkCargs(L, n);
-  luaV_Cclosure(L, fn, n);
   luaC_checkGC(L);
+  luaV_Cclosure(L, fn, n);
 }
 
+
 void lua_pushusertag (lua_State *L, void *u, int tag) {  /* ORDER LUA_T */
+  luaC_checkGC(L);
   if (tag != LUA_ANYTAG && tag != TAG_USERDATA && tag < NUM_TAGS)
     luaL_verror(L, "invalid tag for a userdata (%d)", tag);
   tsvalue(L->top) = luaS_createudata(L, u, tag);
   ttype(L->top) = TAG_USERDATA;
-  incr_top;
-  luaC_checkGC(L);
+  api_incr_top(L);
 }
 
-void luaA_pushobject (lua_State *L, const TObject *o) {
-  *L->top = *o;
-  incr_top;
+
+
+/*
+** get functions (Lua -> stack)
+*/
+
+
+void lua_getglobal (lua_State *L, const char *name) {
+  luaV_getglobal(L, luaS_new(L, name), L->top++);
 }
 
-void lua_pushobject (lua_State *L, lua_Object o) {
-  if (o == LUA_NOOBJECT)
-    lua_error(L, "Lua API error - attempt to push a NOOBJECT");
-  *L->top = *o;
-  incr_top;
+
+void lua_gettable (lua_State *L) {
+  luaV_gettable(L, L->top--);
 }
 
 
-int lua_tag (lua_State *L, lua_Object o) {
-  if (o == LUA_NOOBJECT)
-    return TAG_NIL;
-  else if (ttype(o) == TAG_USERDATA)  /* to allow `old' tags (deprecated) */
-    return tsvalue(o)->u.d.tag;
+void lua_rawget (lua_State *L) {
+  if (ttype(L->top - 2) != TAG_TABLE)
+    lua_error(L, "indexed expression not a table");
+  *(L->top - 2) = *luaH_get(L, hvalue(L->top - 2), L->top - 1);
+  L->top--;
+}
+
+
+void lua_getglobals (lua_State *L) {
+  hvalue(L->top) = L->gt;
+  ttype(L->top) = TAG_TABLE;
+  api_incr_top(L);
+}
+
+
+void lua_gettagmethod (lua_State *L, int tag, const char *event) {
+  *L->top = *luaT_gettagmethod(L, tag, event);
+  api_incr_top(L);
+}
+
+
+int lua_getref (lua_State *L, int ref) {
+  if (ref == LUA_REFNIL)
+    ttype(L->top) = TAG_NIL;
+  else if (0 <= ref && ref < L->refSize &&
+          (L->refArray[ref].st == LOCK || L->refArray[ref].st == HOLD))
+    *L->top = L->refArray[ref].o;
   else
-    return luaT_effectivetag(L, o);
+    return 0;
+  api_incr_top(L);
+  return 1;
+}
+
+
+void lua_newtable (lua_State *L) {
+  luaC_checkGC(L);
+  hvalue(L->top) = luaH_new(L, 0);
+  ttype(L->top) = TAG_TABLE;
+  api_incr_top(L);
 }
 
 
+
+/*
+** set functions (stack -> Lua)
+*/
+
+
+void lua_setglobal (lua_State *L, const char *name) {
+  luaV_setglobal(L, luaS_new(L, name), L->top--);
+}
+
+
+void lua_settable (lua_State *L) {
+  StkId top = L->top;
+  luaV_settable(L, top-3, top);
+  L->top = top-3;  /* pop table, index, and value */
+}
+
+
+void lua_rawset (lua_State *L) {
+  if (ttype(L->top-3) != TAG_TABLE)
+    lua_error(L, "indexed expression not a table");
+  *luaH_set(L, hvalue(L->top-3), L->top-2) = *(L->top-1);
+  L->top -= 3;
+}
+
+
+void lua_setglobals (lua_State *L) {
+  TObject *newtable = --L->top;
+  if (ttype(newtable) != TAG_TABLE)
+    lua_error(L, "Lua API error - invalid value for global table");
+  L->gt = hvalue(newtable);
+}
+
+
+void lua_settagmethod (lua_State *L, int tag, const char *event) {
+  TObject *method = L->top - 1;
+  if (ttype(method) != TAG_NIL &&
+      ttype(method) != TAG_CCLOSURE &&
+      ttype(method) != TAG_LCLOSURE)
+    lua_error(L, "Lua API error - tag method must be a function or nil");
+  luaT_settagmethod(L, tag, event, method);
+}
+
+
+int lua_ref (lua_State *L,  int lock) {
+  int ref;
+  if (ttype(L->top-1) == TAG_NIL)
+    ref = LUA_REFNIL;
+  else {
+    if (L->refFree != NONEXT) {  /* is there a free place? */
+      ref = L->refFree;
+      L->refFree = L->refArray[ref].st;
+    }
+    else {  /* no more free places */
+      luaM_growvector(L, L->refArray, L->refSize, 1, struct Ref,
+                      "reference table overflow", MAX_INT);
+      ref = L->refSize++;
+    }
+    L->refArray[ref].o = *(L->top-1);
+    L->refArray[ref].st = lock ? LOCK : HOLD;
+  }
+  L->top--;
+  return ref;
+}
+
+
+
+/*
+** miscelaneous functions
+*/
+
+
 void lua_settag (lua_State *L, int tag) {
-  luaA_checkCargs(L, 1);
   luaT_realtag(L, tag);
   switch (ttype(L->top-1)) {
     case TAG_TABLE:
@@ -334,6 +341,17 @@ void lua_settag (lua_State *L, int tag) {
 }
 
 
+void lua_unref (lua_State *L, int ref) {
+  if (ref >= 0) {
+    if (ref >= L->refSize || L->refArray[ref].st >= 0)
+      lua_error(L, "Lua API error - "
+                   "invalid argument for function `lua_unref'");
+    L->refArray[ref].st = L->refFree;
+    L->refFree = ref;
+  }
+}
+
+
 int luaA_next (lua_State *L, const Hash *t, int i) {
   int tsize = t->size;
   for (; i<tsize; i++) {
@@ -348,38 +366,10 @@ int luaA_next (lua_State *L, const Hash *t, int i) {
 }
 
 
-int lua_next (lua_State *L, lua_Object t, int i) {
+int lua_next (lua_State *L, int index, int i) {
+  const TObject *t = Index(L, index);
   if (ttype(t) != TAG_TABLE)
     lua_error(L, "Lua API error - object is not a table in `lua_next'"); 
-  i = luaA_next(L, hvalue(t), i);
-  top2LC(L, (i==0) ? 0 : 2);
-  return i;
-}
-
-
-
-#if LUA_DEPRECATETFUNCS
-
-/*
-** obsolete functions
-*/
-
-lua_Object lua_rawgetglobal (lua_State *L, const char *name) {
-  lua_pushglobals(L);
-  lua_pushstring(L, name);
-  return lua_rawget(L);
-}
-
-
-void lua_rawsetglobal (lua_State *L, const char *name) {
-  lua_Object value;
-  lua_beginblock(L);
-  value = lua_pop(L);
-  lua_pushglobals(L);
-  lua_pushstring(L, name);
-  lua_pushobject(L, value);
-  lua_rawset(L);
-  lua_endblock(L);
+  return luaA_next(L, hvalue(t), i);
 }
 
-#endif

+ 2 - 3
lapi.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.h,v 1.17 2000/05/08 19:32:53 roberto Exp roberto $
+** $Id: lapi.h,v 1.18 2000/05/08 20:49:05 roberto Exp roberto $
 ** Auxiliary functions from Lua API
 ** See Copyright Notice in lua.h
 */
@@ -11,9 +11,8 @@
 #include "lobject.h"
 
 
-void luaA_checkCargs (lua_State *L, int nargs);
+TObject *luaA_index (lua_State *L, int index);
 void luaA_pushobject (lua_State *L, const TObject *o);
 int luaA_next (lua_State *L, const Hash *t, int i);
-lua_Object luaA_putluaObject (lua_State *L, const TObject *o);
 
 #endif

+ 29 - 39
lauxlib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lauxlib.c,v 1.29 2000/06/12 13:52:05 roberto Exp roberto $
+** $Id: lauxlib.c,v 1.30 2000/08/09 19:16:57 roberto Exp roberto $
 ** Auxiliary functions for building Lua libraries
 ** See Copyright Notice in lua.h
 */
@@ -41,72 +41,61 @@ void luaL_argerror (lua_State *L, int narg, const char *extramsg) {
 }
 
 
-static void type_error (lua_State *L, int narg, const char *type_name,
-                        lua_Object o) {
+static void type_error (lua_State *L, int narg, const char *type_name) {
   char buff[100];
-  const char *otype = (o == LUA_NOOBJECT) ? "no value" : lua_type(L, o);
-  sprintf(buff, "%.10s expected, got %.10s", type_name, otype);
+  const char *rt = lua_type(L, narg);
+  if (*rt == 'N') rt = "no value";
+  sprintf(buff, "%.10s expected, got %.10s", type_name, rt);
   luaL_argerror(L, narg, buff);
 }
 
 
-static const char *checkstr (lua_State *L, lua_Object o, int narg,
-                             size_t *len) {
-  const char *s = lua_getstring(L, o);
-  if (!s) type_error(L, narg, "string", o);
-  if (len) *len = lua_strlen(L, o);
+/*
+** use the 3rd letter of type names for testing:
+** nuMber, niL, stRing, fuNction, usErdata, taBle, anY
+*/
+void luaL_checktype(lua_State *L, int narg, const char *tname) {
+  const char *rt = lua_type(L, narg);
+  if (!(*rt != 'N' && (tname[2] == 'y' || tname[2] == rt[2])))
+    type_error(L, narg, tname);
+}
+
+
+static const char *checkstr (lua_State *L, int narg, size_t *len) {
+  const char *s = lua_tostring(L, narg);
+  if (!s) type_error(L, narg, "string");
+  if (len) *len = lua_strlen(L, narg);
   return s;
 }
 
 const char *luaL_check_lstr (lua_State *L, int narg, size_t *len) {
-  return checkstr(L, lua_getparam(L, narg), narg, len);
+  return checkstr(L, narg, len);
 }
 
 const char *luaL_opt_lstr (lua_State *L, int narg, const char *def,
                            size_t *len) {
-  lua_Object o = lua_getparam(L, narg);
-  if (o == LUA_NOOBJECT) {
+  if (lua_isnull(L, narg)) {
     if (len) *len = def ? strlen(def) : 0;
     return def;
   }
-  else return checkstr(L, o, narg, len);
+  else return checkstr(L, narg, len);
 }
 
 double luaL_check_number (lua_State *L, int narg) {
-  lua_Object o = lua_getparam(L, narg);
-  if (!lua_isnumber(L, o)) type_error(L, narg, "number", o);
-  return lua_getnumber(L, o);
+  if (!lua_isnumber(L, narg)) type_error(L, narg, "number");
+  return lua_tonumber(L, narg);
 }
 
 
 double luaL_opt_number (lua_State *L, int narg, double def) {
-  lua_Object o = lua_getparam(L, narg);
-  if (o == LUA_NOOBJECT) return def;
+  if (lua_isnull(L, narg)) return def;
   else {
-    if (!lua_isnumber(L, o)) type_error(L, narg, "number", o);
-    return lua_getnumber(L, o);
+    if (!lua_isnumber(L, narg)) type_error(L, narg, "number");
+    return lua_tonumber(L, narg);
   }
 }
 
 
-lua_Object luaL_tablearg (lua_State *L, int narg) {
-  lua_Object o = lua_getparam(L, narg);
-  if (!lua_istable(L, o)) type_error(L, narg, "table", o);
-  return o;
-}
-
-lua_Object luaL_functionarg (lua_State *L, int narg) {
-  lua_Object o = lua_getparam(L, narg);
-  if (!lua_isfunction(L, o)) type_error(L, narg, "function", o);
-  return o;
-}
-
-lua_Object luaL_nonnullarg (lua_State *L, int narg) {
-  lua_Object o = lua_getparam(L, narg);
-  luaL_arg_check(L, o != LUA_NOOBJECT, narg, "value expected");
-  return o;
-}
-
 void luaL_openlib (lua_State *L, const struct luaL_reg *l, int n) {
   int i;
   for (i=0; i<n; i++)
@@ -150,3 +139,4 @@ void luaL_filesource (char *out, const char *filename, int len) {
   if (filename == NULL) filename = "(stdin)";
   sprintf(out, "@%.*s", len-2, filename);  /* -2 for '@' and '\0' */
 }
+

+ 5 - 7
lauxlib.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lauxlib.h,v 1.18 2000/05/24 13:54:49 roberto Exp roberto $
+** $Id: lauxlib.h,v 1.19 2000/08/09 19:16:57 roberto Exp roberto $
 ** Auxiliary functions for building Lua libraries
 ** See Copyright Notice in lua.h
 */
@@ -27,14 +27,15 @@ const char *luaL_opt_lstr (lua_State *L, int numArg, const char *def,
                            size_t *len);
 double luaL_check_number (lua_State *L, int numArg);
 double luaL_opt_number (lua_State *L, int numArg, double def);
-lua_Object luaL_functionarg (lua_State *L, int arg);
-lua_Object luaL_tablearg (lua_State *L, int arg);
-lua_Object luaL_nonnullarg (lua_State *L, int numArg);
+
+void luaL_checktype(lua_State *L, int narg, const char *tname);
+
 void luaL_verror (lua_State *L, const char *fmt, ...);
 int luaL_findstring (const char *name, const char *const list[]);
 void luaL_chunkid (char *out, const char *source, int len);
 void luaL_filesource (char *out, const char *filename, int len);
 
+
 char *luaL_openspace (lua_State *L, size_t size);
 void luaL_resetbuffer (lua_State *L);
 void luaL_addchar (lua_State *L, int c);
@@ -91,9 +92,6 @@ char *luaL_buffer (lua_State *L);
 				(luaL_opt_lstr)(lua_state,numArg,def,len)
 #define luaL_check_number(numArg)	(luaL_check_number)(lua_state,numArg)
 #define luaL_opt_number(numArg,def)	(luaL_opt_number)(lua_state,numArg,def)
-#define luaL_functionarg(arg)	(luaL_functionarg)(lua_state,arg)
-#define luaL_tablearg(arg)	(luaL_tablearg)(lua_state,arg)
-#define luaL_nonnullarg(numArg)	(luaL_nonnullarg)(lua_state,numArg)
 #define luaL_openspace(size)	(luaL_openspace)(lua_state,size)
 #define luaL_resetbuffer()	(luaL_resetbuffer)(lua_state)
 #define luaL_addchar(c)		(luaL_addchar)(lua_state,c)

+ 187 - 150
lbuiltin.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lbuiltin.c,v 1.120 2000/08/14 19:10:14 roberto Exp roberto $
+** $Id: lbuiltin.c,v 1.121 2000/08/15 18:28:48 roberto Exp roberto $
 ** Built-in functions
 ** See Copyright Notice in lua.h
 */
@@ -50,7 +50,6 @@ void luaB_opentests (lua_State *L);
 ** =======================================================
 */
 
-
 static Number getsize (const Hash *h) {
   Number max = 0;
   int i = h->size;
@@ -73,7 +72,8 @@ static Number getnarg (lua_State *L, const Hash *a) {
 
 
 static Hash *gettable (lua_State *L, int arg) {
-  return hvalue(luaL_tablearg(L, arg));
+  luaL_checktype(L, arg, "table");
+  return hvalue(luaA_index(L, arg));
 }
 
 /* }====================================================== */
@@ -90,8 +90,9 @@ static Hash *gettable (lua_State *L, int arg) {
 ** If your system does not support `stderr', redefine this function, or
 ** redefine _ERRORMESSAGE so that it won't need _ALERT.
 */
-void luaB__ALERT (lua_State *L) {
+int luaB__ALERT (lua_State *L) {
   fputs(luaL_check_string(L, 1), stderr);
+  return 0;
 }
 
 
@@ -99,18 +100,19 @@ void luaB__ALERT (lua_State *L) {
 ** Standard implementation of _ERRORMESSAGE.
 ** The library `liolib' redefines _ERRORMESSAGE for better error information.
 */
-void luaB__ERRORMESSAGE (lua_State *L) {
-  lua_Object al;
-  lua_pushglobals(L);
+int luaB__ERRORMESSAGE (lua_State *L) {
+  lua_getglobals(L);
   lua_pushstring(L, LUA_ALERT);
-  al = lua_rawget(L);
-  if (lua_isfunction(L, al)) {  /* avoid error loop if _ALERT is not defined */
+  lua_rawget(L);
+  if (lua_isfunction(L, -1)) {  /* avoid error loop if _ALERT is not defined */
     const char *s = luaL_check_string(L, 1);
     char *buff = luaL_openspace(L, strlen(s)+sizeof("error: \n"));
     strcpy(buff, "error: "); strcat(buff, s); strcat(buff, "\n");
+    lua_pushobject(L, -1);  /* function to be called */
     lua_pushstring(L, buff);
-    lua_callfunction(L, al);
+    lua_call(L, 1, 0);
   }
+  return 0;
 }
 
 
@@ -120,36 +122,35 @@ void luaB__ERRORMESSAGE (lua_State *L) {
 ** model but changing `fputs' to put the strings at a proper place
 ** (a console window or a log file, for instance).
 */
-void luaB_print (lua_State *L) {
-  lua_Object args[MAXPRINT];
-  lua_Object obj;
-  int n = 0;
+int luaB_print (lua_State *L) {
+  int n = lua_gettop(L);  /* number of arguments */
   int i;
-  while ((obj = lua_getparam(L, n+1)) != LUA_NOOBJECT) {
-    luaL_arg_check(L, n < MAXPRINT, n+1, "too many arguments");
-    args[n++] = obj;
-  }
-  for (i=0; i<n; i++) {
-    lua_pushobject(L, args[i]);
-    if (lua_call(L, "tostring"))
+  lua_getglobal(L, "tostring");
+  for (i=1; i<=n; i++) {
+    const char *s;
+    lua_pushobject(L, -1);  /* function to be called */
+    lua_pushobject(L, i);
+    if (lua_call(L, 1, 1) != 0)
       lua_error(L, "error in `tostring' called by `print'");
-    obj = lua_getresult(L, 1);
-    if (!lua_isstring(L, obj))
+    s = lua_tostring(L, -1);  /* get result */
+    if (s == NULL)
       lua_error(L, "`tostring' must return a string to `print'");
-    if (i>0) fputs("\t", stdout);
-    fputs(lua_getstring(L, obj), stdout);
+    if (i>1) fputs("\t", stdout);
+    fputs(s, stdout);
+    lua_settop(L, -1);  /* pop result */
   }
   fputs("\n", stdout);
+  return 0;
 }
 
 
-void luaB_tonumber (lua_State *L) {
+int luaB_tonumber (lua_State *L) {
   int base = luaL_opt_int(L, 2, 10);
   if (base == 10) {  /* standard conversion */
-    lua_Object o = luaL_nonnullarg(L, 1);
-    if (lua_isnumber(L, o)) {
-      lua_pushnumber(L, lua_getnumber(L, o));
-      return;
+    luaL_checktype(L, 1, "any");
+    if (lua_isnumber(L, 1)) {
+      lua_pushnumber(L, lua_tonumber(L, 1));
+      return 1;
     }
   }
   else {
@@ -162,94 +163,108 @@ void luaB_tonumber (lua_State *L) {
       while (isspace((unsigned char)*s2)) s2++;  /* skip trailing spaces */
       if (*s2 == '\0') {  /* no invalid trailing characters? */
         lua_pushnumber(L, n);
-        return;
+        return 1;
       }
     }
   }
   lua_pushnil(L);  /* else not a number */
+  return 1;
 }
 
 
-void luaB_error (lua_State *L) {
+int luaB_error (lua_State *L) {
   lua_error(L, luaL_opt_string(L, 1, NULL));
+  return 0;  /* to avoid errors */
 }
 
-void luaB_setglobal (lua_State *L) {
-  const char *name = luaL_check_string(L, 1);
-  lua_Object value = luaL_nonnullarg(L, 2);
-  lua_pushobject(L, value);
-  lua_setglobal(L, name);
+int luaB_setglobal (lua_State *L) {
+  luaL_checktype(L, 2, "any");
+  lua_setglobal(L, luaL_check_string(L, 1));
+  return 0;
 }
 
-void luaB_getglobal (lua_State *L) {
-  lua_pushobject(L, lua_getglobal(L, luaL_check_string(L, 1)));
+int luaB_getglobal (lua_State *L) {
+  lua_getglobal(L, luaL_check_string(L, 1));
+  return 1;
 }
 
-void luaB_tag (lua_State *L) {
-  lua_pushnumber(L, lua_tag(L, luaL_nonnullarg(L, 1)));
+int luaB_tag (lua_State *L) {
+  luaL_checktype(L, 1, "any");
+  lua_pushnumber(L, lua_tag(L, 1));
+  return 1;
 }
 
-void luaB_settag (lua_State *L) {
-  lua_Object o = luaL_tablearg(L, 1);
-  lua_pushobject(L, o);
+int luaB_settag (lua_State *L) {
+  luaL_checktype(L, 1, "table");
+  lua_pushobject(L, 1);  /* push table */
   lua_settag(L, luaL_check_int(L, 2));
-  lua_pushobject(L, o);  /* return first argument */
+  lua_pushobject(L, 1);  /* return first argument */
+  return 1;
 }
 
-void luaB_newtag (lua_State *L) {
+int luaB_newtag (lua_State *L) {
   lua_pushnumber(L, lua_newtag(L));
+  return 1;
 }
 
-void luaB_copytagmethods (lua_State *L) {
+int luaB_copytagmethods (lua_State *L) {
   lua_pushnumber(L, lua_copytagmethods(L, luaL_check_int(L, 1),
                                           luaL_check_int(L, 2)));
+  return 1;
 }
 
-void luaB_globals (lua_State *L) {
-  lua_pushglobals(L);
-  if (lua_getparam(L, 1) != LUA_NOOBJECT)
-    lua_setglobals(L, luaL_tablearg(L, 1));
+int luaB_globals (lua_State *L) {
+  lua_getglobals(L);  /* value to be returned */
+  if (!lua_isnull(L, 1)) {
+    luaL_checktype(L, 1, "table");
+    lua_pushobject(L, 1);  /* new table of globals */
+    lua_setglobals(L);
+  }
+  return 1;
 }
 
-void luaB_rawget (lua_State *L) {
-  lua_pushobject(L, luaL_nonnullarg(L, 1));
-  lua_pushobject(L, luaL_nonnullarg(L, 2));
-  lua_pushobject(L, lua_rawget(L));
+int luaB_rawget (lua_State *L) {
+  luaL_checktype(L, 1, "table");
+  luaL_checktype(L, 2, "any");
+  lua_rawget(L);
+  return 1;
 }
 
-void luaB_rawset (lua_State *L) {
-  lua_pushobject(L, luaL_nonnullarg(L, 1));
-  lua_pushobject(L, luaL_nonnullarg(L, 2));
-  lua_pushobject(L, luaL_nonnullarg(L, 3));
+int luaB_rawset (lua_State *L) {
+  luaL_checktype(L, 1, "table");
+  luaL_checktype(L, 2, "any");
+  luaL_checktype(L, 3, "any");
   lua_rawset(L);
+  return 1;
 }
 
-void luaB_settagmethod (lua_State *L) {
-  int tag = luaL_check_int(L, 1);
+int luaB_settagmethod (lua_State *L) {
+  int tag = (int)luaL_check_int(L, 1);
   const char *event = luaL_check_string(L, 2);
-  lua_Object nf = luaL_nonnullarg(L, 3);
-  luaL_arg_check(L, lua_isnil(L, nf) || lua_isfunction(L, nf), 3,
+  luaL_arg_check(L, lua_isfunction(L, 3) || lua_isnil(L, 3), 3,
                  "function or nil expected");
   if (strcmp(event, "gc") == 0 && tag != TAG_NIL)
     lua_error(L, "deprecated use: cannot set the `gc' tag method from Lua");
-  lua_pushobject(L, nf);
-  lua_pushobject(L, lua_settagmethod(L, tag, event));
+  lua_settagmethod(L, tag, event);
+  return 1;
 }
 
-void luaB_gettagmethod (lua_State *L) {
-  lua_pushobject(L, lua_gettagmethod(L, luaL_check_int(L, 1),
-                                        luaL_check_string(L, 2)));
+int luaB_gettagmethod (lua_State *L) {
+  lua_gettagmethod(L, luaL_check_int(L, 1), luaL_check_string(L, 2));
+  return 1;
 }
 
 
-void luaB_collectgarbage (lua_State *L) {
+int luaB_collectgarbage (lua_State *L) {
   lua_pushnumber(L, lua_collectgarbage(L, luaL_opt_int(L, 1, 0)));
+  return 1;
 }
 
 
-void luaB_type (lua_State *L) {
-  lua_Object o = luaL_nonnullarg(L, 1);
-  lua_pushstring(L, lua_type(L, o));
+int luaB_type (lua_State *L) {
+  luaL_checktype(L, 1, "any");
+  lua_pushstring(L, lua_type(L, 1));
+  return 1;
 }
 
 /* }====================================================== */
@@ -263,99 +278,115 @@ void luaB_type (lua_State *L) {
 */
 
 
-static void passresults (lua_State *L) {
-  L->Cstack.base = L->Cstack.lua2C;  /* position of first result */
-  if (L->Cstack.num == 0)
-    lua_pushuserdata(L, NULL);  /* at least one result to signal no errors */
+static int passresults (lua_State *L, int status, int oldtop) {
+  if (status == 0) {
+    int nresults = lua_gettop(L) - oldtop;
+    if (nresults > 0)
+      return nresults;  /* results are already on the stack */
+    else {
+      lua_pushuserdata(L, NULL);  /* at least one result to signal no errors */
+      return 1;
+    }
+  }
+  else {  /* error */
+    lua_pushnil(L);
+    lua_pushnumber(L, status);  /* error code */
+    return 2;
+  }
 }
 
-void luaB_dostring (lua_State *L) {
+int luaB_dostring (lua_State *L) {
+  int oldtop = lua_gettop(L);
   size_t l;
   const char *s = luaL_check_lstr(L, 1, &l);
   if (*s == ID_CHUNK)
     lua_error(L, "`dostring' cannot run pre-compiled code");
-  if (lua_dobuffer(L, s, l, luaL_opt_string(L, 2, s)) == 0)
-    passresults(L);
-  else
-    lua_pushnil(L);
+  return passresults(L, lua_dobuffer(L, s, l, luaL_opt_string(L, 2, s)), oldtop);
 }
 
 
-void luaB_dofile (lua_State *L) {
+int luaB_dofile (lua_State *L) {
+  int oldtop = lua_gettop(L);
   const char *fname = luaL_opt_string(L, 1, NULL);
-  if (lua_dofile(L, fname) == 0)
-    passresults(L);
-  else
-    lua_pushnil(L);
+  return passresults(L, lua_dofile(L, fname), oldtop);
 }
 
 
-void luaB_call (lua_State *L) {
-  lua_Object f = luaL_nonnullarg(L, 1);
+int luaB_call (lua_State *L) {
+  int oldtop;
   const Hash *arg = gettable(L, 2);
   const char *options = luaL_opt_string(L, 3, "");
-  lua_Object err = lua_getparam(L, 4);
-  int narg = (int)getnarg(L, arg);
+  int err = 0;  /* index of old error method */
+  int n = (int)getnarg(L, arg);
   int i, status;
-  if (err != LUA_NOOBJECT) {  /* set new error method */
-    lua_Object oldem = lua_getglobal(L, LUA_ERRORMESSAGE);
-    lua_pushobject(L, err);
+  if (!lua_isnull(L, 4)) {  /* set new error method */
+    lua_getglobal(L, LUA_ERRORMESSAGE);
+    err = lua_gettop(L);  /* get index */
+    lua_pushobject(L, 4);
     lua_setglobal(L, LUA_ERRORMESSAGE);
-    err = oldem;
   }
+  oldtop = lua_gettop(L);  /* top before function-call preparation */
+  /* push function */
+  lua_pushobject(L, 1);
   /* push arg[1...n] */
-  luaD_checkstack(L, narg);
-  for (i=0; i<narg; i++)
+  luaD_checkstack(L, n);
+  for (i=0; i<n; i++)
     *(L->top++) = *luaH_getnum(arg, i+1);
-  status = lua_callfunction(L, f);
-  if (err != LUA_NOOBJECT) {  /* restore old error method */
+  status = lua_call(L, n, LUA_MULTRET);
+  n = lua_gettop(L) - oldtop;  /* number of results */
+  if (err != 0) {  /* restore old error method */
     lua_pushobject(L, err);
     lua_setglobal(L, LUA_ERRORMESSAGE);
   }
   if (status != 0) {  /* error in call? */
-    if (strchr(options, 'x')) {
-      lua_pushnil(L);
-      return;  /* return nil to signal the error */
-    }
+    if (strchr(options, 'x'))
+      lua_pushnil(L);  /* return nil to signal the error */
     else
       lua_error(L, NULL);  /* propagate error without additional messages */
+    return 1;
   }
   else {  /* no errors */
     if (strchr(options, 'p')) {  /* pack results? */
-      luaV_pack(L, L->Cstack.lua2C, L->Cstack.num, L->top);
+      luaV_pack(L, luaA_index(L, oldtop+1), n, L->top);
       incr_top;
+      return 1;  /* only table is returned */
     }
     else
-      L->Cstack.base = L->Cstack.lua2C;  /* position of first result */
+      return n;  /* results are already on the stack */
   }
 }
 
 
-void luaB_next (lua_State *L) {
+int luaB_next (lua_State *L) {
   const Hash *a = gettable(L, 1);
-  lua_Object k = lua_getparam(L, 2);
   int i;  /* `luaA_next' gets first element after `i' */
-  if (k == LUA_NOOBJECT || ttype(k) == TAG_NIL)
+  if (lua_isnull(L, 2) || lua_isnil(L, 2))  /* no index or nil index? */
     i = 0;  /* get first */
   else {
-    i = luaH_pos(L, a, k)+1;
+    i = luaH_pos(L, a, luaA_index(L, 2))+1;
     luaL_arg_check(L, i != 0, 2, "key not found");
   }
-  if (luaA_next(L, a, i) == 0)
+  if (luaA_next(L, a, i) != 0)
+    return 2;  /* `luaA_next' left them on the stack */
+  else {
     lua_pushnil(L);
+    return 1;
+  }
 }
 
 
-void luaB_tostring (lua_State *L) {
-  lua_Object o = luaL_nonnullarg(L, 1);
+int luaB_tostring (lua_State *L) {
   char buff[64];
+  const TObject *o;
+  luaL_checktype(L, 1, "any");
+  o = luaA_index(L, 1);
   switch (ttype(o)) {
     case TAG_NUMBER:
-      lua_pushstring(L, lua_getstring(L, o));
-      return;
+      lua_pushstring(L, lua_tostring(L, 1));
+      return 1;
     case TAG_STRING:
-      lua_pushobject(L, o);
-      return;
+      lua_pushobject(L, 1);
+      return 1;
     case TAG_TABLE:
       sprintf(buff, "table: %p", hvalue(o));
       break;
@@ -368,11 +399,12 @@ void luaB_tostring (lua_State *L) {
       break;
     case TAG_NIL:
       lua_pushstring(L, "nil");
-      return;
+      return 1;
     default:
       LUA_INTERNALERROR("invalid type");
   }
   lua_pushstring(L, buff);
+  return 1;
 }
 
 /* }====================================================== */
@@ -389,15 +421,17 @@ void luaB_tostring (lua_State *L) {
 ** =======================================================
 */
 
-void luaB_assert (lua_State *L) {
-  lua_Object p = luaL_nonnullarg(L, 1);
-  if (lua_isnil(L, p))
+int luaB_assert (lua_State *L) {
+  luaL_checktype(L, 1, "any");
+  if (lua_isnil(L, 1))
     luaL_verror(L, "assertion failed!  %.90s", luaL_opt_string(L, 2, ""));
+  return 0;
 }
 
 
-void luaB_getn (lua_State *L) {
+int luaB_getn (lua_State *L) {
   lua_pushnumber(L, getnarg(L, gettable(L, 1)));
+  return 1;
 }
 
 
@@ -408,72 +442,72 @@ static void t_move (lua_State *L, Hash *t, int from, int to) {
 }
 
 
-void luaB_tinsert (lua_State *L) {
+int luaB_tinsert (lua_State *L) {
   Hash *a = gettable(L, 1);
-  lua_Object v = lua_getparam(L, 3);
   int n = (int)getnarg(L, a);
+  int v = lua_gettop(L);  /* last argument: to be inserted */
   int pos;
-  if (v != LUA_NOOBJECT)
-    pos = luaL_check_int(L, 2);
-  else {  /* called with only 2 arguments */
-    v = luaL_nonnullarg(L, 2);
+  if (v == 2)  /* called with only 2 arguments */
     pos = n+1;
-  }
+  else
+    pos = luaL_check_int(L, 2);  /* 2nd argument is the position */
   luaH_setstrnum(L, a, luaS_new(L, "n"), n+1);  /* a.n = n+1 */
   for (; n>=pos; n--)
     t_move(L, a, n, n+1);  /* a[n+1] = a[n] */
-  *luaH_setint(L, a, pos) = *v;  /* a[pos] = v */
+  *luaH_setint(L, a, pos) = *luaA_index(L, v);  /* a[pos] = v */
+  return 0;
 }
 
 
-void luaB_tremove (lua_State *L) {
+int luaB_tremove (lua_State *L) {
   Hash *a = gettable(L, 1);
   int n = (int)getnarg(L, a);
   int pos = luaL_opt_int(L, 2, n);
-  if (n <= 0) return;  /* table is "empty" */
+  if (n <= 0) return 0;  /* table is "empty" */
   luaA_pushobject(L, luaH_getnum(a, pos));  /* result = a[pos] */
   for ( ;pos<n; pos++)
     t_move(L, a, pos+1, pos);  /* a[pos] = a[pos+1] */
   luaH_setstrnum(L, a, luaS_new(L, "n"), n-1);  /* a.n = n-1 */
   ttype(luaH_setint(L, a, n)) = TAG_NIL;  /* a[n] = nil */
+  return 1;
 }
 
 
-static void luaB_foreachi (lua_State *L) {
+static int luaB_foreachi (lua_State *L) {
   const Hash *t = gettable(L, 1);
   int n = (int)getnarg(L, t);
   int i;
-  lua_Object f = luaL_functionarg(L, 2);
-  luaD_checkstack(L, 3);  /* for f, key, and val */
+  luaL_checktype(L, 2, "function");
   for (i=1; i<=n; i++) {
-    *(L->top++) = *f;
+    lua_pushobject(L, 2);
     ttype(L->top) = TAG_NUMBER; nvalue(L->top++) = i;
     *(L->top++) = *luaH_getnum(t, i);
     luaD_call(L, L->top-3, 1);
     if (ttype(L->top-1) != TAG_NIL)
-      return;
+      return 1;
     L->top--;  /* remove nil result */
   }
+  return 0;
 }
 
 
-static void luaB_foreach (lua_State *L) {
+static int luaB_foreach (lua_State *L) {
   const Hash *a = gettable(L, 1);
-  lua_Object f = luaL_functionarg(L, 2);
   int i;
-  luaD_checkstack(L, 3);  /* for f, key, and val */
+  luaL_checktype(L, 2, "function");
   for (i=0; i<a->size; i++) {
     const Node *nd = &(a->node[i]);
     if (ttype(val(nd)) != TAG_NIL) {
-      *(L->top++) = *f;
+      lua_pushobject(L, 2);
       *(L->top++) = *key(nd);
       *(L->top++) = *val(nd);
       luaD_call(L, L->top-3, 1);
       if (ttype(L->top-1) != TAG_NIL)
-        return;
+        return 1;
       L->top--;  /* remove result */
     }
   }
+  return 0;
 }
 
 
@@ -492,10 +526,10 @@ static void swap (lua_State *L, Hash *a, int i, int j) {
   *luaH_setint(L, a, j) = temp;
 }
 
-static int sort_comp (lua_State *L, lua_Object f, const TObject *a,
-                                                  const TObject *b) {
+static int sort_comp (lua_State *L, const TObject *f, const TObject *a,
+                                                      const TObject *b) {
   /* WARNING: the caller (auxsort) must ensure stack space */
-  if (f != LUA_NOOBJECT) {
+  if (f != NULL) {
     *(L->top) = *f;
     *(L->top+1) = *a;
     *(L->top+2) = *b;
@@ -508,7 +542,7 @@ static int sort_comp (lua_State *L, lua_Object f, const TObject *a,
     return luaV_lessthan(L, a, b, L->top);
 }
 
-static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) {
+static void auxsort (lua_State *L, Hash *a, int l, int u, const TObject *f) {
   StkId P = L->top++;  /* temporary place for pivot */
   ttype(P) = TAG_NIL;
   while (l < u) {  /* for tail recursion */
@@ -552,14 +586,16 @@ static void auxsort (lua_State *L, Hash *a, int l, int u, lua_Object f) {
   L->top--;  /* remove pivot from stack */
 }
 
-void luaB_sort (lua_State *L) {
+int luaB_sort (lua_State *L) {
   Hash *a = gettable(L, 1);
   int n = (int)getnarg(L, a);
-  lua_Object func = lua_getparam(L, 2);
-  luaL_arg_check(L, func == LUA_NOOBJECT || lua_isfunction(L, func), 2,
-                 "function expected");
-  luaD_checkstack(L, 4);  /* for pivot, f, a, b (sort_comp) */
+  const TObject *func = NULL;
+  if (!lua_isnull(L, 2)) {  /* is there a 2nd argument? */
+    luaL_checktype(L, 2, "function");
+    func = luaA_index(L, 2);
+  }
   auxsort(L, a, 1, n, func);
+  return 0;
 }
 
 /* }====================================================== */
@@ -615,8 +651,9 @@ static void deprecated_funcs (lua_State *L) {
 /*
 ** gives an explicit error in any attempt to call a deprecated function
 */
-static void deprecated_func (lua_State *L) {
+static int deprecated_func (lua_State *L) {
   luaL_verror(L, "function `%.20s' is deprecated", luaL_check_string(L, 1));
+  return 0;  /* to avoid warnings */
 }
 
 

+ 29 - 29
lbuiltin.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lbuiltin.h,v 1.8 2000/05/08 19:32:53 roberto Exp roberto $
+** $Id: lbuiltin.h,v 1.9 2000/05/26 19:17:57 roberto Exp roberto $
 ** Built-in functions
 ** See Copyright Notice in lua.h
 */
@@ -9,34 +9,34 @@
 
 #include "lua.h"
 
-void luaB__ALERT (lua_State *L);
-void luaB__ERRORMESSAGE (lua_State *L);
-void luaB_assert (lua_State *L);
-void luaB_call (lua_State *L);
-void luaB_collectgarbage (lua_State *L);
-void luaB_copytagmethods (lua_State *L);
-void luaB_dofile (lua_State *L);
-void luaB_dostring (lua_State *L);
-void luaB_error (lua_State *L);
-void luaB_getglobal (lua_State *L);
-void luaB_getn (lua_State *L);
-void luaB_gettagmethod (lua_State *L);
-void luaB_globals (lua_State *L);
-void luaB_newtag (lua_State *L);
-void luaB_next (lua_State *L);
-void luaB_print (lua_State *L);
-void luaB_rawget (lua_State *L);
-void luaB_rawset (lua_State *L);
-void luaB_setglobal (lua_State *L);
-void luaB_settag (lua_State *L);
-void luaB_settagmethod (lua_State *L);
-void luaB_sort (lua_State *L);
-void luaB_tag (lua_State *L);
-void luaB_tinsert (lua_State *L);
-void luaB_tonumber (lua_State *L);
-void luaB_tostring (lua_State *L);
-void luaB_tremove (lua_State *L);
-void luaB_type (lua_State *L);
+int luaB__ALERT (lua_State *L);
+int luaB__ERRORMESSAGE (lua_State *L);
+int luaB_assert (lua_State *L);
+int luaB_call (lua_State *L);
+int luaB_collectgarbage (lua_State *L);
+int luaB_copytagmethods (lua_State *L);
+int luaB_dofile (lua_State *L);
+int luaB_dostring (lua_State *L);
+int luaB_error (lua_State *L);
+int luaB_getglobal (lua_State *L);
+int luaB_getn (lua_State *L);
+int luaB_gettagmethod (lua_State *L);
+int luaB_globals (lua_State *L);
+int luaB_newtag (lua_State *L);
+int luaB_next (lua_State *L);
+int luaB_print (lua_State *L);
+int luaB_rawget (lua_State *L);
+int luaB_rawset (lua_State *L);
+int luaB_setglobal (lua_State *L);
+int luaB_settag (lua_State *L);
+int luaB_settagmethod (lua_State *L);
+int luaB_sort (lua_State *L);
+int luaB_tag (lua_State *L);
+int luaB_tinsert (lua_State *L);
+int luaB_tonumber (lua_State *L);
+int luaB_tostring (lua_State *L);
+int luaB_tremove (lua_State *L);
+int luaB_type (lua_State *L);
 
 void luaB_predefine (lua_State *L);
 

+ 49 - 55
ldblib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldblib.c,v 1.17 2000/06/12 13:52:05 roberto Exp roberto $
+** $Id: ldblib.c,v 1.18 2000/08/09 19:16:57 roberto Exp roberto $
 ** Interface from Lua to its debug API
 ** See Copyright Notice in lua.h
 */
@@ -17,102 +17,96 @@
 
 
 
-static void settabss (lua_State *L, lua_Object t, const char *i, const char *v) {
-  lua_pushobject(L, t);
+static void settabss (lua_State *L, const char *i, const char *v) {
+  lua_pushobject(L, -1);
   lua_pushstring(L, i);
   lua_pushstring(L, v);
   lua_settable(L);
 }
 
 
-static void settabsi (lua_State *L, lua_Object t, const char *i, int v) {
-  lua_pushobject(L, t);
+static void settabsi (lua_State *L, const char *i, int v) {
+  lua_pushobject(L, -1);
   lua_pushstring(L, i);
   lua_pushnumber(L, v);
   lua_settable(L);
 }
 
 
-static void settabso (lua_State *L, lua_Object t, const char *i, lua_Object v) {
-  lua_pushobject(L, t);
-  lua_pushstring(L, i);
-  lua_pushobject(L, v);
-  lua_settable(L);
-}
-
-
-static void getinfo (lua_State *L) {
+static int getinfo (lua_State *L) {
   lua_Debug ar;
-  lua_Object res;
-  lua_Object func = lua_getparam(L, 1);
   const char *options = luaL_opt_string(L, 2, "flnSu");
   char buff[20];
-  if (lua_isnumber(L, func)) {
-    if (!lua_getstack(L, (int)lua_getnumber(L, func), &ar)) {
+  if (lua_isnumber(L, 1)) {
+    if (!lua_getstack(L, (int)lua_tonumber(L, 1), &ar)) {
       lua_pushnil(L);  /* level out of range */
-      return;
+      return 1;
     }
   }
-  else if (lua_isfunction(L, func)) {
-    ar.func = func;
+  else if (lua_isfunction(L, 1)) {
+    lua_pushobject(L, 1);
     sprintf(buff, ">%.10s", options);
     options = buff;
   }
   else
     luaL_argerror(L, 1, "function or level expected");
-  res = lua_createtable(L);
   if (!lua_getinfo(L, options, &ar))
     luaL_argerror(L, 2, "invalid option");
+  lua_newtable(L);
   for (; *options; options++) {
     switch (*options) {
       case 'S':
-        settabss(L, res, "source", ar.source);
-        settabsi(L, res, "linedefined", ar.linedefined);
-        settabss(L, res, "what", ar.what);
+        settabss(L, "source", ar.source);
+        settabsi(L, "linedefined", ar.linedefined);
+        settabss(L, "what", ar.what);
         break;
       case 'l':
-        settabsi(L, res, "currentline", ar.currentline);
+        settabsi(L, "currentline", ar.currentline);
         break;
       case 'u':
-        settabsi(L, res, "nups", ar.nups);
+        settabsi(L, "nups", ar.nups);
         break;
       case 'n':
-        settabss(L, res, "name", ar.name);
-        settabss(L, res, "namewhat", ar.namewhat);
+        settabss(L, "name", ar.name);
+        settabss(L, "namewhat", ar.namewhat);
         break;
       case 'f':
-        settabso(L, res, "func", ar.func);
+        lua_pushobject(L, -1);
+        lua_pushstring(L, "func");
+        lua_pushobject(L, -4);
+        lua_settable(L);
         break;
     }
   }
-  lua_pushobject(L, res);
+  return 1;  /* return table */
 }
     
 
-static void getlocal (lua_State *L) {
+static int getlocal (lua_State *L) {
   lua_Debug ar;
-  lua_Localvar lvar;
+  const char *name;
   if (!lua_getstack(L, luaL_check_int(L, 1), &ar))  /* level out of range? */
     luaL_argerror(L, 1, "level out of range");
-  lvar.index = luaL_check_int(L, 2);
-  if (lua_getlocal(L, &ar, &lvar)) {
-    lua_pushstring(L, lvar.name);
-    lua_pushobject(L, lvar.value);
+  name = lua_getlocal(L, &ar, luaL_check_int(L, 2));
+  if (name) {
+    lua_pushstring(L, name);
+    lua_pushobject(L, -2);
+    return 2;
+  }
+  else {
+    lua_pushnil(L);
+    return 1;
   }
-  else lua_pushnil(L);
 }
 
 
-static void setlocal (lua_State *L) {
+static int setlocal (lua_State *L) {
   lua_Debug ar;
-  lua_Localvar lvar;
   if (!lua_getstack(L, luaL_check_int(L, 1), &ar))  /* level out of range? */
     luaL_argerror(L, 1, "level out of range");
-  lvar.index = luaL_check_int(L, 2);
-  lvar.value = luaL_nonnullarg(L, 3);
-  if (lua_setlocal(L, &ar, &lvar))
-    lua_pushstring(L, lvar.name);
-  else lua_pushnil(L);
+  luaL_checktype(L, 3, "any");
+  lua_pushstring(L, lua_setlocal(L, &ar, luaL_check_int(L, 2)));
+  return 1;
 }
 
 
@@ -128,47 +122,47 @@ static int callhook = LUA_NOREF;  /* Lua reference to call hook function */
 
 static void linef (lua_State *L, lua_Debug *ar) {
   if (linehook != LUA_NOREF) {
+    lua_getref(L, linehook);
     lua_pushnumber(L, ar->currentline);
-    lua_callfunction(L, lua_getref(L, linehook));
+    lua_call(L, 1, 0);
   }
 }
 
 
 static void callf (lua_State *L, lua_Debug *ar) {
   if (callhook != LUA_NOREF) {
+    lua_getref(L, callhook);
     lua_pushstring(L, ar->event);
-    lua_callfunction(L, lua_getref(L, callhook));
+    lua_call(L, 1, 0);
   }
 }
 
 
-static void setcallhook (lua_State *L) {
-  lua_Object f = lua_getparam(L, 1);
+static int setcallhook (lua_State *L) {
   lua_unref(L, callhook);
-  if (f == LUA_NOOBJECT) {
+  if (lua_isnull(L, 1)) {
     callhook = LUA_NOREF;
     lua_setcallhook(L, NULL);
   }
   else {
-    lua_pushobject(L, f);
     callhook = lua_ref(L, 1);
     lua_setcallhook(L, callf);
   }
+  return 0;
 }
 
 
-static void setlinehook (lua_State *L) {
-  lua_Object f = lua_getparam(L, 1);
+static int setlinehook (lua_State *L) {
   lua_unref(L, linehook);
-  if (f == LUA_NOOBJECT) {
+  if (lua_isnull(L, 1)) {
     linehook = LUA_NOREF;
     lua_setlinehook(L, NULL);
   }
   else {
-    lua_pushobject(L, f);
     linehook = lua_ref(L, 1);
     lua_setlinehook(L, linef);
   }
+  return 0;
 }
 
 

+ 21 - 19
ldebug.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldebug.c,v 1.35 2000/08/14 17:59:20 roberto Exp roberto $
+** $Id: ldebug.c,v 1.36 2000/08/15 18:28:48 roberto Exp roberto $
 ** Debug Interface
 ** See Copyright Notice in lua.h
 */
@@ -144,26 +144,28 @@ static Proto *getluaproto (StkId f) {
 }
 
 
-int lua_getlocal (lua_State *L, const lua_Debug *ar, lua_Localvar *v) {
+const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int localnum) {
+  const char *name;
   StkId f = ar->_func;
   Proto *fp = getluaproto(f);
-  if (!fp) return 0;  /* `f' is not a Lua function? */
-  v->name = luaF_getlocalname(fp, v->index, lua_currentpc(f));
-  if (!v->name) return 0;
-  v->value = luaA_putluaObject(L, (f+1)+(v->index-1));
-  return 1;
+  if (!fp) return NULL;  /* `f' is not a Lua function? */
+  name = luaF_getlocalname(fp, localnum, lua_currentpc(f));
+  if (!name) return NULL;
+  luaA_pushobject(L, (f+1)+(localnum-1));  /* push value */
+  return name;
 }
 
 
-int lua_setlocal (lua_State *L, const lua_Debug *ar, lua_Localvar *v) {
+const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int localnum) {
+  const char *name;
   StkId f = ar->_func;
   Proto *fp = getluaproto(f);
   UNUSED(L);
-  if (!fp) return 0;  /* `f' is not a Lua function? */
-  v->name = luaF_getlocalname(fp, v->index, lua_currentpc(f));
-  if (!v->name || v->name[0] == '*') return 0;  /* `*' starts private locals */
-  *((f+1)+(v->index-1)) = *v->value;
-  return 1;
+  if (!fp) return NULL;  /* `f' is not a Lua function? */
+  name = luaF_getlocalname(fp, localnum, lua_currentpc(f));
+  if (!name || name[0] == '*') return NULL;  /* `*' starts private locals */
+  *((f+1)+(localnum-1)) = *(--L->top);
+  return name;
 }
 
 
@@ -236,7 +238,7 @@ int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
     func = ar->_func;
   else {
     what++;  /* skip the '>' */
-    func = ar->func;
+    func = L->top - 1;
   }
   for (; *what; what++) {
     switch (*what) {
@@ -260,13 +262,13 @@ int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
       }
       case 'f': {
         setnormalized(L->top, func);
-        incr_top;
-        ar->func = lua_pop(L);
+        incr_top;  /* push function */
         break;
       }
       default: return 0;  /* invalid option */
     }
   }
+  if (!isactive) L->top--;  /* pop function */
   return 1;
 }
 
@@ -420,7 +422,7 @@ static const char *getfuncname (lua_State *L, StkId f, const char **name) {
 void luaG_typeerror (lua_State *L, StkId o, const char *op) {
   const char *name;
   const char *kind = getobjname(L, o, &name);
-  const char *t = lua_type(L, o);
+  const char *t = luaO_typename(o);
   if (kind)
     luaL_verror(L, "attempt to %.30s %.20s `%.40s' (a %.10s value)",
                 op, kind, name, t);
@@ -437,8 +439,8 @@ void luaG_binerror (lua_State *L, StkId p1, lua_Type t, const char *op) {
 
 
 void luaG_ordererror (lua_State *L, StkId top) {
-  const char *t1 = lua_type(L, top-2);
-  const char *t2 = lua_type(L, top-1);
+  const char *t1 = luaO_typename(top-2);
+  const char *t2 = luaO_typename(top-1);
   if (t1[2] == t2[2])
     luaL_verror(L, "attempt to compare two %.10s values", t1);
   else

+ 35 - 52
ldo.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.c,v 1.84 2000/08/09 19:16:57 roberto Exp roberto $
+** $Id: ldo.c,v 1.85 2000/08/10 19:50:47 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -41,8 +41,7 @@ void luaD_init (lua_State *L, int stacksize) {
   L->stack = luaM_newvector(L, stacksize+EXTRA_STACK, TObject);
   L->stack_last = L->stack+(stacksize-1);
   L->stacksize = stacksize;
-  L->Cstack.base = L->Cstack.lua2C = L->top = L->stack;
-  L->Cstack.num = 0;
+  L->Cbase = L->top = L->stack;
 }
 
 
@@ -68,8 +67,8 @@ void luaD_checkstack (lua_State *L, int n) {
 
 
 static void restore_stack_limit (lua_State *L) {
-  if (L->top-L->stack < L->stacksize-1)
-    L->stack_last = L->stack+(L->stacksize-1);
+  if (L->top - L->stack < L->stacksize - 1)
+    L->stack_last = L->stack + (L->stacksize-1);
 }
 
 
@@ -103,9 +102,8 @@ void luaD_openstack (lua_State *L, StkId pos) {
 void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook) {
   if (L->allowhooks) {
     lua_Debug ar;
-    struct C_Lua_Stack oldCLS = L->Cstack;
-    StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->top;
-    L->Cstack.num = 0;
+    StkId old_Cbase = L->Cbase;
+    StkId old_top = L->Cbase = L->top;
     ar._func = func;
     ar.event = "line";
     ar.currentline = line;
@@ -113,7 +111,7 @@ void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook) {
     (*linehook)(L, &ar);
     L->allowhooks = 1;
     L->top = old_top;
-    L->Cstack = oldCLS;
+    L->Cbase = old_Cbase;
   }
 }
 
@@ -122,42 +120,36 @@ static void luaD_callHook (lua_State *L, StkId func, lua_Hook callhook,
                     const char *event) {
   if (L->allowhooks) {
     lua_Debug ar;
-    struct C_Lua_Stack oldCLS = L->Cstack;
-    StkId old_top = L->Cstack.lua2C = L->Cstack.base = L->top;
-    L->Cstack.num = 0;
+    StkId old_Cbase = L->Cbase;
+    StkId old_top = L->Cbase = L->top;
     ar._func = func;
     ar.event = event;
     L->allowhooks = 0;  /* cannot call hooks inside a hook */
     callhook(L, &ar);
     L->allowhooks = 1;
     L->top = old_top;
-    L->Cstack = oldCLS;
+    L->Cbase = old_Cbase;
   }
 }
 
 
 static StkId callCclosure (lua_State *L, const struct Closure *cl, StkId base) {
   int nup = cl->nupvalues;  /* number of upvalues */
-  int numarg = L->top-base;
-  struct C_Lua_Stack oldCLS = L->Cstack;
-  StkId firstResult;
+  StkId old_Cbase = L->Cbase;
+  int nres;  /* number of results */
   if (nup > 0) {
-    int n = numarg;
+    int n = L->top - base;  /* number of arguments */
     luaD_checkstack(L, nup);
     /* open space for upvalues as extra arguments */
     while (n--) *(base+nup+n) = *(base+n);
     L->top += nup;
-    numarg += nup;
     /* copy upvalues into stack */
     while (nup--) *(base+nup) = cl->upvalue[nup];
   }
-  L->Cstack.num = numarg;
-  L->Cstack.lua2C = base;
-  L->Cstack.base = L->top;
-  (*cl->f.c)(L);  /* do the actual call */
-  firstResult = L->Cstack.base;
-  L->Cstack = oldCLS;
-  return firstResult;
+  L->Cbase = base;       /* new base for C function */
+  nres = (*cl->f.c)(L);  /* do the actual call */
+  L->Cbase = old_Cbase;  /* restore old C base */
+  return L->top - nres;  /* return index of first result */
 }
 
 
@@ -257,42 +249,36 @@ void lua_error (lua_State *L, const char *s) {
 
 
 static void chain_longjmp (lua_State *L, struct lua_longjmp *lj) {
-  lj->base = L->Cstack.base;
-  lj->numCblocks = L->numCblocks;
+  lj->status = 0;
+  lj->base = L->Cbase;
   lj->previous = L->errorJmp;
   L->errorJmp = lj;
 }
 
 
-static void restore_longjmp (lua_State *L, struct lua_longjmp *lj) {
-  L->Cstack.num = 0;  /* no results */
-  L->top = L->Cstack.base = L->Cstack.lua2C = lj->base;
-  L->numCblocks = lj->numCblocks;
+static int restore_longjmp (lua_State *L, struct lua_longjmp *lj) {
+  L->Cbase = lj->base;
   L->errorJmp = lj->previous;
+  return lj->status;
 }
 
 
 /*
-** Execute a protected call. Assumes that function is at Cstack.base and
-** parameters are on top of it.
+** Execute a protected call.
 */
-int luaD_protectedrun (lua_State *L) {
+int lua_call (lua_State *L, int nargs, int nresults) {
+  StkId func = L->top - (nargs+1);  /* function to be called */
   struct lua_longjmp myErrorJmp;
   chain_longjmp(L, &myErrorJmp);
+  if (nresults == LUA_MULTRET) nresults = MULT_RET;  /* internal code */
   if (setjmp(myErrorJmp.b) == 0) {
-    StkId base = L->Cstack.base;
-    luaD_call(L, base, MULT_RET);
-    L->Cstack.lua2C = base;  /* position of the new results */
-    L->Cstack.num = L->top - base;
-    L->Cstack.base = base + L->Cstack.num;  /* incorporate results on stack */
-    L->errorJmp = myErrorJmp.previous;
-    return 0;
+    luaD_call(L, func, nresults);
   }
-  else {  /* an error occurred: restore the stack */
-    restore_longjmp(L, &myErrorJmp);
+  else {  /* an error occurred: restore the state */
+    L->top = func;  /* remove garbage from the stack */
     restore_stack_limit(L);
-    return myErrorJmp.status;
   }
+  return restore_longjmp(L, &myErrorJmp);
 }
 
 
@@ -302,20 +288,17 @@ int luaD_protectedrun (lua_State *L) {
 static int protectedparser (lua_State *L, ZIO *z, int bin) {
   struct lua_longjmp myErrorJmp;
   chain_longjmp(L, &myErrorJmp);
-  L->top = L->Cstack.base;   /* clear C2Lua */
   if (setjmp(myErrorJmp.b) == 0) {
     Proto *tf = bin ? luaU_undump1(L, z) : luaY_parser(L, z);
-    L->errorJmp = myErrorJmp.previous;
-    if (tf == NULL) return -1;  /* `natural' end */
+    if (tf == NULL)
+      myErrorJmp.status = -1;  /* `natural' end */
     luaV_Lclosure(L, tf, 0);
-    return 0;
   }
-  else {  /* an error occurred */
-    restore_longjmp(L, &myErrorJmp);
+  else {  /* an error occurred: correct error code */
     if (myErrorJmp.status == LUA_ERRRUN)
       myErrorJmp.status = LUA_ERRSYNTAX;
-    return myErrorJmp.status;  /* error code */
   }
+  return restore_longjmp(L, &myErrorJmp);  /* error code */
 }
 
 
@@ -331,7 +314,7 @@ static int do_main (lua_State *L, ZIO *z, int bin) {
     else {
       unsigned long newelems2 = 2*(L->nblocks-old_blocks);
       L->GCthreshold += newelems2;
-      status = luaD_protectedrun(L);
+      status = lua_call(L, 0, LUA_MULTRET);
       L->GCthreshold -= newelems2;
     }
   } while (bin && status == 0);

+ 1 - 2
ldo.h

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.h,v 1.21 2000/06/28 20:21:06 roberto Exp roberto $
+** $Id: ldo.h,v 1.22 2000/08/07 18:39:16 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -26,7 +26,6 @@ void luaD_lineHook (lua_State *L, StkId func, int line, lua_Hook linehook);
 void luaD_call (lua_State *L, StkId func, int nResults);
 void luaD_callTM (lua_State *L, const TObject *f, int nParams, int nResults);
 void luaD_breakrun (lua_State *L, int errcode);
-int luaD_protectedrun (lua_State *L);
 void luaD_checkstack (lua_State *L, int n);
 
 

+ 39 - 3
lgc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.c,v 1.62 2000/08/09 19:16:57 roberto Exp roberto $
+** $Id: lgc.c,v 1.63 2000/08/22 17:44:17 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -11,7 +11,6 @@
 #include "lgc.h"
 #include "lmem.h"
 #include "lobject.h"
-#include "lref.h"
 #include "lstate.h"
 #include "lstring.h"
 #include "ltable.h"
@@ -145,6 +144,43 @@ static void markall (lua_State *L) {
 }
 
 
+static int hasmark (const TObject *o) {
+  /* valid only for locked objects */
+  switch (o->ttype) {
+    case TAG_STRING: case TAG_USERDATA:
+      return tsvalue(o)->marked;
+    case TAG_TABLE:
+      return ismarked(hvalue(o));
+    case TAG_LCLOSURE:  case TAG_CCLOSURE:
+      return ismarked(clvalue(o)->mark);
+    default:  /* number */
+      return 1;
+  }
+}
+
+
+/* macro for internal debugging; check if a link of free refs is valid */
+#define VALIDLINK(L, st,n)      (NONEXT <= (st) && (st) < (n))
+
+static void invalidaterefs (lua_State *L) {
+  int n = L->refSize;
+  int i;
+  for (i=0; i<n; i++) {
+    struct Ref *r = &L->refArray[i];
+    if (r->st == HOLD && !hasmark(&r->o))
+      r->st = COLLECTED;
+    LUA_ASSERT((r->st == LOCK && hasmark(&r->o)) ||
+               (r->st == HOLD && hasmark(&r->o)) ||
+                r->st == COLLECTED ||
+                r->st == NONEXT ||
+               (r->st < n && VALIDLINK(L, L->refArray[r->st].st, n)),
+               "inconsistent ref table");
+  }
+  LUA_ASSERT(VALIDLINK(L, L->refFree, n), "inconsistent ref table");
+}
+
+
+
 static void collectproto (lua_State *L) {
   Proto **p = &L->rootproto;
   Proto *next;
@@ -300,7 +336,7 @@ void luaC_collect (lua_State *L, int all) {
 long lua_collectgarbage (lua_State *L, long limit) {
   unsigned long recovered = L->nblocks;  /* to subtract `nblocks' after gc */
   markall(L);
-  luaR_invalidaterefs(L);
+  invalidaterefs(L);
   luaC_collect(L, 0);
   recovered = recovered - L->nblocks;
   L->GCthreshold = (limit == 0) ? 2*L->nblocks : L->nblocks+limit;

+ 109 - 87
liolib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: liolib.c,v 1.70 2000/08/14 19:10:14 roberto Exp roberto $
+** $Id: liolib.c,v 1.71 2000/08/22 17:47:17 roberto Exp roberto $
 ** Standard I/O (and system) library
 ** See Copyright Notice in lua.h
 */
@@ -61,13 +61,16 @@ typedef struct IOCtrl {
 static const char *const filenames[] = {"_INPUT", "_OUTPUT"};
 
 
-static void pushresult (lua_State *L, int i) {
-  if (i)
+static int pushresult (lua_State *L, int i) {
+  if (i) {
     lua_pushuserdata(L, NULL);
+    return 1;
+  }
   else {
     lua_pushnil(L);
     lua_pushstring(L, strerror(errno));
     lua_pushnumber(L, errno);
+    return 3;;
   }
 }
 
@@ -79,8 +82,8 @@ static void pushresult (lua_State *L, int i) {
 */
 
 
-static FILE *gethandle (lua_State *L, IOCtrl *ctrl, lua_Object f) {
-  void *p = lua_getuserdata(L, f);
+static FILE *gethandle (lua_State *L, IOCtrl *ctrl, int f) {
+  void *p = lua_touserdata(L, f);
   if (p != NULL) {  /* is `f' a userdata ? */
     int ftag = lua_tag(L, f);
     if (ftag == ctrl->iotag)  /* does it have the correct tag? */
@@ -94,7 +97,7 @@ static FILE *gethandle (lua_State *L, IOCtrl *ctrl, lua_Object f) {
 
 
 static FILE *getnonullfile (lua_State *L, IOCtrl *ctrl, int arg) {
-  FILE *f = gethandle(L, ctrl, lua_getparam(L, arg));
+  FILE *f = gethandle(L, ctrl, arg);
   luaL_arg_check(L, f, arg, "invalid file handle");
   return f;
 }
@@ -102,9 +105,11 @@ static FILE *getnonullfile (lua_State *L, IOCtrl *ctrl, int arg) {
 
 static FILE *getfilebyref (lua_State *L, IOCtrl *ctrl, int inout) {
   FILE *f;
-  lua_pushglobals(L);
-  lua_pushref(L, ctrl->ref[inout]);
-  f = gethandle(L, ctrl, lua_rawget(L));
+  lua_getglobals(L);
+  lua_getref(L, ctrl->ref[inout]);
+  lua_rawget(L);
+  f = gethandle(L, ctrl, -1);
+  lua_settop(L, -1);  /* remove global */
   if (f == NULL)
     luaL_verror(L, "global variable `%.10s' is not a file handle",
                 filenames[inout]);
@@ -122,12 +127,13 @@ static void setfilebyname (lua_State *L, IOCtrl *ctrl, FILE *f,
 #define setfile(L,ctrl,f,inout)	(setfilebyname(L,ctrl,f,filenames[inout]))
 
 
-static void setreturn (lua_State *L, IOCtrl *ctrl, FILE *f, int inout) {
+static int setreturn (lua_State *L, IOCtrl *ctrl, FILE *f, int inout) {
   if (f == NULL)
-    pushresult(L, 0);
+    return pushresult(L, 0);
   else {
     setfile(L, ctrl, f, inout);
     lua_pushusertag(L, f, ctrl->iotag);
+    return 1;
   }
 }
 
@@ -143,15 +149,15 @@ static int closefile (lua_State *L, IOCtrl *ctrl, FILE *f) {
 }
 
 
-static void io_close (lua_State *L) {
-  IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1));
-  pushresult(L, closefile(L, ctrl, getnonullfile(L, ctrl, 2)));
+static int io_close (lua_State *L) {
+  IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1);
+  return pushresult(L, closefile(L, ctrl, getnonullfile(L, ctrl, 2)));
 }
 
 
-static void file_collect (lua_State *L) {
-  IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1));
-  if (ctrl == (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 2))) {
+static int file_collect (lua_State *L) {
+  IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1);
+  if (ctrl == (IOCtrl *)lua_touserdata(L, 2)) {
     /* collectig `ctrl' itself */
     lua_unref(L, ctrl->ref[INFILE]);
     lua_unref(L, ctrl->ref[OUTFILE]);
@@ -162,50 +168,54 @@ static void file_collect (lua_State *L) {
     if (f != stdin && f != stdout && f != stderr)
       CLOSEFILE(L, f);
   }
+  return 0;
 }
 
 
-static void io_open (lua_State *L) {
-  IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1));
+static int io_open (lua_State *L) {
+  IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1);
   FILE *f = fopen(luaL_check_string(L, 2), luaL_check_string(L, 3));
-  if (f) lua_pushusertag(L, f, ctrl->iotag);
-  else pushresult(L, 0);
+  if (f) {
+    lua_pushusertag(L, f, ctrl->iotag);
+    return 1;
+  }
+  else
+    return pushresult(L, 0);
 }
 
 
 
-static void io_fromto (lua_State *L, int inout, const char *mode) {
-  IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1));
-  lua_Object f = lua_getparam(L, 2);
+static int io_fromto (lua_State *L, int inout, const char *mode) {
+  IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1);
   FILE *current;
-  if (f == LUA_NOOBJECT) {
+  if (lua_isnull(L, 2)) {
     closefile(L, ctrl, getfilebyref(L, ctrl, inout));
     current = (inout == 0) ? stdin : stdout;    
   }
-  else if (lua_tag(L, f) == ctrl->iotag)  /* deprecated option */
-    current = (FILE *)lua_getuserdata(L, f);
+  else if (lua_tag(L, 2) == ctrl->iotag)  /* deprecated option */
+    current = (FILE *)lua_touserdata(L, 2);
   else {
     const char *s = luaL_check_string(L, 2);
     current = (*s == '|') ? popen(s+1, mode) : fopen(s, mode);
   }
-  setreturn(L, ctrl, current, inout);
+  return setreturn(L, ctrl, current, inout);
 }
 
 
-static void io_readfrom (lua_State *L) {
-  io_fromto(L, INFILE, "r");
+static int io_readfrom (lua_State *L) {
+  return io_fromto(L, INFILE, "r");
 }
 
 
-static void io_writeto (lua_State *L) {
-  io_fromto(L, OUTFILE, "w");
+static int io_writeto (lua_State *L) {
+  return io_fromto(L, OUTFILE, "w");
 }
 
 
-static void io_appendto (lua_State *L) {
-  IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1));
+static int io_appendto (lua_State *L) {
+  IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1);
   FILE *current = fopen(luaL_check_string(L, 2), "a");
-  setreturn(L, ctrl, current, OUTFILE);
+  return setreturn(L, ctrl, current, OUTFILE);
 }
 
 
@@ -342,28 +352,29 @@ static int read_chars (lua_State *L, FILE *f, size_t n) {
 }
 
 
-static void io_read (lua_State *L) {
-  IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1));
-  int arg = 2;
-  lua_Object op;
-  FILE *f = gethandle(L, ctrl, lua_getparam(L, arg));
-  if (f) arg++;
+static int io_read (lua_State *L) {
+  IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1);
+  int lastarg = lua_gettop(L);
+  int firstarg = 2;
+  FILE *f = gethandle(L, ctrl, firstarg);
+  int n = 0;
+  if (f) firstarg++;
   else f = getfilebyref(L, ctrl, INFILE);  /* get _INPUT */
-  op = lua_getparam(L, arg);
   do {  /* repeat for each part */
     size_t l;
     int success;
     luaL_resetbuffer(L);
-    if (lua_isnumber(L, op))
-      success = read_chars(L, f, (size_t)lua_getnumber(L, op));
+    if (lua_isnumber(L, firstarg+n))
+      success = read_chars(L, f, (size_t)lua_tonumber(L, firstarg+n));
     else {
-      const char *p = luaL_opt_string(L, arg, "*l");
+      const char *p = luaL_opt_string(L, firstarg+n, "*l");
       if (p[0] != '*')
         success = read_pattern(L, f, p);  /* deprecated! */
       else {
         switch (p[1]) {
           case 'n':  /* number */
-            if (!read_number(L, f)) return;  /* read fails */
+            if (!read_number(L, f)) return n;  /* read fails */
+            n++;
             continue;  /* number is already pushed; avoid the "pushstring" */
           case 'l':  /* line */
             success = read_line(L, f);
@@ -377,66 +388,69 @@ static void io_read (lua_State *L) {
             success = 0;  /* must read something to succeed */
             break;
           default:
-            luaL_argerror(L, arg, "invalid format");
+            luaL_argerror(L, firstarg+n, "invalid format");
             success = 0;  /* to avoid warnings */
         }
       }
     }
     l = luaL_getsize(L);
-    if (!success && l==0) return;  /* read fails */
+    if (!success && l==0) return n;  /* read fails */
     lua_pushlstring(L, luaL_buffer(L), l);
-  } while ((op = lua_getparam(L, ++arg)) != LUA_NOOBJECT);
+    n++;
+  } while (firstarg+n <= lastarg);
+  return n;
 }
 
 /* }====================================================== */
 
 
-static void io_write (lua_State *L) {
-  IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1));
+static int io_write (lua_State *L) {
+  int lastarg = lua_gettop(L);
+  IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1);
   int arg = 2;
   int status = 1;
-  lua_Object o;
-  FILE *f = gethandle(L, ctrl, lua_getparam(L, arg));
+  FILE *f = gethandle(L, ctrl, arg);
   if (f) arg++;
   else f = getfilebyref(L, ctrl, OUTFILE);  /* get _OUTPUT */
-  while ((o = lua_getparam(L, arg)) != LUA_NOOBJECT) {
-    if (lua_type(L, o)[2] == 'm') {  /* nuMber? */  /* LUA_NUMBER */
+  for (; arg <=  lastarg; arg++) {
+    if (lua_type(L, arg)[2] == 'm') {  /* nuMber? */  /* LUA_NUMBER */
       /* optimization: could be done exactly as for strings */
-      status = status && fprintf(f, "%.16g", lua_getnumber(L, o)) > 0;
+      status = status && fprintf(f, "%.16g", lua_tonumber(L, arg)) > 0;
     }
     else {
       size_t l;
       const char *s = luaL_check_lstr(L, arg, &l);
       status = status && (fwrite(s, sizeof(char), l, f) == l);
     }
-    arg++;
   }
   pushresult(L, status);
+  return 1;
 }
 
 
-static void io_seek (lua_State *L) {
+static int io_seek (lua_State *L) {
   static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
   static const char *const modenames[] = {"set", "cur", "end", NULL};
-  IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1));
+  IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1);
   FILE *f = getnonullfile(L, ctrl, 2);
   int op = luaL_findstring(luaL_opt_string(L, 3, "cur"), modenames);
   long offset = luaL_opt_long(L, 4, 0);
   luaL_arg_check(L, op != -1, 3, "invalid mode");
   op = fseek(f, offset, mode[op]);
   if (op)
-    pushresult(L, 0);  /* error */
-  else
+    return pushresult(L, 0);  /* error */
+  else {
     lua_pushnumber(L, ftell(f));
+    return 1;
+  }
 }
 
 
-static void io_flush (lua_State *L) {
-  IOCtrl *ctrl = (IOCtrl *)lua_getuserdata(L, lua_getparam(L, 1));
-  lua_Object of = lua_getparam(L, 2);
-  FILE *f = gethandle(L, ctrl, of);
-  luaL_arg_check(L, f || of == LUA_NOOBJECT, 2, "invalid file handle");
-  pushresult(L, fflush(f) == 0);
+static int io_flush (lua_State *L) {
+  IOCtrl *ctrl = (IOCtrl *)lua_touserdata(L, 1);
+  FILE *f = gethandle(L, ctrl, 2);
+  luaL_arg_check(L, f || lua_isnull(L, 2), 2, "invalid file handle");
+  return pushresult(L, fflush(f) == 0);
 }
 
 /* }====================================================== */
@@ -448,39 +462,43 @@ static void io_flush (lua_State *L) {
 ** =======================================================
 */
 
-static void io_execute (lua_State *L) {
+static int io_execute (lua_State *L) {
   lua_pushnumber(L, system(luaL_check_string(L, 1)));
+  return 1;
 }
 
 
-static void io_remove (lua_State *L) {
-  pushresult(L, remove(luaL_check_string(L, 1)) == 0);
+static int io_remove (lua_State *L) {
+  return pushresult(L, remove(luaL_check_string(L, 1)) == 0);
 }
 
 
-static void io_rename (lua_State *L) {
-  pushresult(L, rename(luaL_check_string(L, 1),
+static int io_rename (lua_State *L) {
+  return pushresult(L, rename(luaL_check_string(L, 1),
                     luaL_check_string(L, 2)) == 0);
 }
 
 
-static void io_tmpname (lua_State *L) {
+static int io_tmpname (lua_State *L) {
   lua_pushstring(L, tmpnam(NULL));
+  return 1;
 }
 
 
 
-static void io_getenv (lua_State *L) {
+static int io_getenv (lua_State *L) {
   lua_pushstring(L, getenv(luaL_check_string(L, 1)));  /* if NULL push nil */
+  return 1;
 }
 
 
-static void io_clock (lua_State *L) {
+static int io_clock (lua_State *L) {
   lua_pushnumber(L, ((double)clock())/CLOCKS_PER_SEC);
+  return 1;
 }
 
 
-static void io_date (lua_State *L) {
+static int io_date (lua_State *L) {
   char b[256];
   const char *s = luaL_opt_string(L, 1, "%c");
   struct tm *stm;
@@ -490,10 +508,11 @@ static void io_date (lua_State *L) {
     lua_pushstring(L, b);
   else
     lua_error(L, "invalid `date' format");
+  return 1;
 }
 
 
-static void setloc (lua_State *L) {
+static int setloc (lua_State *L) {
   static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
                       LC_NUMERIC, LC_TIME};
   static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
@@ -501,25 +520,28 @@ static void setloc (lua_State *L) {
   int op = luaL_findstring(luaL_opt_string(L, 2, "all"), catnames);
   luaL_arg_check(L, op != -1, 2, "invalid option");
   lua_pushstring(L, setlocale(cat[op], luaL_check_string(L, 1)));
+  return 1;
 }
 
 
-static void io_exit (lua_State *L) {
+static int io_exit (lua_State *L) {
   exit(luaL_opt_int(L, 1, EXIT_SUCCESS));
+  return 0;  /* to avoid warnings */
 }
 
 /* }====================================================== */
 
 
 
-static void io_debug (lua_State *L) {
+static int io_debug (lua_State *L) {
   for (;;) {
     char buffer[250];
     fprintf(stderr, "lua_debug> ");
     if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
         strcmp(buffer, "cont\n") == 0)
-      return;
+      return 0;
     lua_dostring(L, buffer);
+    lua_settop(L, 0);  /* remove eventual returns */
   }
 }
 
@@ -529,12 +551,11 @@ static void io_debug (lua_State *L) {
 #define MAXMESSAGE (MESSAGESIZE*10)
 
 
-static void errorfb (lua_State *L) {
+static int errorfb (lua_State *L) {
   char buff[MAXMESSAGE];
   int level = 1;  /* skip level 0 (it's this function) */
   lua_Debug ar;
-  lua_Object alertfunc;
-  sprintf(buff, "error: %.200s\n", lua_getstring(L, lua_getparam(L, 1)));
+  sprintf(buff, "error: %.200s\n", lua_tostring(L, 1));
   while (lua_getstack(L, level++, &ar)) {
     char buffchunk[60];
     lua_getinfo(L, "Snl", &ar);
@@ -572,13 +593,14 @@ static void errorfb (lua_State *L) {
       sprintf(buff+strlen(buff), " [%.70s]", buffchunk);
     strcat(buff, "\n");
   }
-  lua_pushglobals(L);
+  lua_getglobals(L);
   lua_pushstring(L, LUA_ALERT);
-  alertfunc = lua_rawget(L);
-  if (lua_isfunction(L, alertfunc)) {  /* avoid loop if _ALERT is not defined */
+  lua_rawget(L);
+  if (lua_isfunction(L, -1)) {  /* avoid loop if _ALERT is not defined */
     lua_pushstring(L, buff);
-    lua_callfunction(L, alertfunc);
+    lua_call(L, 1, 0);
   }
+  return 0;
 }
 
 

+ 1 - 7
llimits.h

@@ -1,5 +1,5 @@
 /*
-** $Id: llimits.h,v 1.11 2000/06/28 17:03:32 roberto Exp roberto $
+** $Id: llimits.h,v 1.12 2000/08/15 18:28:48 roberto Exp roberto $
 ** Limits, basic types, and some other "installation-dependent" definitions
 ** See Copyright Notice in lua.h
 */
@@ -197,12 +197,6 @@ typedef unsigned long Instruction;
 #define RFIELDS_PER_FLUSH	(LFIELDS_PER_FLUSH/2)
 
 
-/* maximum number of values printed in one call to `print' */
-#ifndef MAXPRINT
-#define MAXPRINT        40	/* arbitrary limit */
-#endif
-
-
 /* maximum lookback to find a real constant (for code generation) */
 #ifndef LOOKBACKNUMS
 #define LOOKBACKNUMS    20      /* arbitrary constant */

+ 77 - 45
lmathlib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lmathlib.c,v 1.25 2000/06/12 13:52:05 roberto Exp roberto $
+** $Id: lmathlib.c,v 1.26 2000/08/09 19:16:57 roberto Exp roberto $
 ** Standard mathematical library
 ** See Copyright Notice in lua.h
 */
@@ -33,138 +33,169 @@
 #endif
 
 
-static void math_abs (lua_State *L) {
+static int math_abs (lua_State *L) {
   lua_pushnumber(L, fabs(luaL_check_number(L, 1)));
+  return 1;
 }
 
-static void math_sin (lua_State *L) {
+static int math_sin (lua_State *L) {
   lua_pushnumber(L, sin(TORAD(luaL_check_number(L, 1))));
+  return 1;
 }
 
-static void math_cos (lua_State *L) {
+static int math_cos (lua_State *L) {
   lua_pushnumber(L, cos(TORAD(luaL_check_number(L, 1))));
+  return 1;
 }
 
-static void math_tan (lua_State *L) {
+static int math_tan (lua_State *L) {
   lua_pushnumber(L, tan(TORAD(luaL_check_number(L, 1))));
+  return 1;
 }
 
-static void math_asin (lua_State *L) {
+static int math_asin (lua_State *L) {
   lua_pushnumber(L, FROMRAD(asin(luaL_check_number(L, 1))));
+  return 1;
 }
 
-static void math_acos (lua_State *L) {
+static int math_acos (lua_State *L) {
   lua_pushnumber(L, FROMRAD(acos(luaL_check_number(L, 1))));
+  return 1;
 }
 
-static void math_atan (lua_State *L) {
+static int math_atan (lua_State *L) {
   lua_pushnumber(L, FROMRAD(atan(luaL_check_number(L, 1))));
+  return 1;
 }
 
-static void math_atan2 (lua_State *L) {
+static int math_atan2 (lua_State *L) {
   lua_pushnumber(L, FROMRAD(atan2(luaL_check_number(L, 1), luaL_check_number(L, 2))));
+  return 1;
 }
 
-static void math_ceil (lua_State *L) {
+static int math_ceil (lua_State *L) {
   lua_pushnumber(L, ceil(luaL_check_number(L, 1)));
+  return 1;
 }
 
-static void math_floor (lua_State *L) {
+static int math_floor (lua_State *L) {
   lua_pushnumber(L, floor(luaL_check_number(L, 1)));
+  return 1;
 }
 
-static void math_mod (lua_State *L) {
+static int math_mod (lua_State *L) {
   lua_pushnumber(L, fmod(luaL_check_number(L, 1), luaL_check_number(L, 2)));
+  return 1;
 }
 
-static void math_sqrt (lua_State *L) {
+static int math_sqrt (lua_State *L) {
   lua_pushnumber(L, sqrt(luaL_check_number(L, 1)));
+  return 1;
 }
 
-static void math_pow (lua_State *L) {
+static int math_pow (lua_State *L) {
   lua_pushnumber(L, pow(luaL_check_number(L, 1), luaL_check_number(L, 2)));
+  return 1;
 }
 
-static void math_log (lua_State *L) {
+static int math_log (lua_State *L) {
   lua_pushnumber(L, log(luaL_check_number(L, 1)));
+  return 1;
 }
 
-static void math_log10 (lua_State *L) {
+static int math_log10 (lua_State *L) {
   lua_pushnumber(L, log10(luaL_check_number(L, 1)));
+  return 1;
 }
 
-static void math_exp (lua_State *L) {
+static int math_exp (lua_State *L) {
   lua_pushnumber(L, exp(luaL_check_number(L, 1)));
+  return 1;
 }
 
-static void math_deg (lua_State *L) {
+static int math_deg (lua_State *L) {
   lua_pushnumber(L, luaL_check_number(L, 1)/RADIANS_PER_DEGREE);
+  return 1;
 }
 
-static void math_rad (lua_State *L) {
+static int math_rad (lua_State *L) {
   lua_pushnumber(L, luaL_check_number(L, 1)*RADIANS_PER_DEGREE);
+  return 1;
 }
 
-static void math_frexp (lua_State *L) {
+static int math_frexp (lua_State *L) {
   int e;
   lua_pushnumber(L, frexp(luaL_check_number(L, 1), &e));
   lua_pushnumber(L, e);
+  return 2;
 }
 
-static void math_ldexp (lua_State *L) {
+static int math_ldexp (lua_State *L) {
   lua_pushnumber(L, ldexp(luaL_check_number(L, 1), luaL_check_int(L, 2)));
+  return 1;
 }
 
 
 
-static void math_min (lua_State *L) {
-  int i = 1;
-  double dmin = luaL_check_number(L, i);
-  while (lua_getparam(L, ++i) != LUA_NOOBJECT) {
+static int math_min (lua_State *L) {
+  int n = lua_gettop(L);  /* number of arguments */
+  double dmin = luaL_check_number(L, 1);
+  int i;
+  for (i=2; i<=n; i++) {
     double d = luaL_check_number(L, i);
     if (d < dmin)
       dmin = d;
   }
   lua_pushnumber(L, dmin);
+  return 1;
 }
 
 
-static void math_max (lua_State *L) {
-  int i = 1;
-  double dmax = luaL_check_number(L, i);
-  while (lua_getparam(L, ++i) != LUA_NOOBJECT) {
+static int math_max (lua_State *L) {
+  int n = lua_gettop(L);  /* number of arguments */
+  double dmax = luaL_check_number(L, 1);
+  int i;
+  for (i=2; i<=n; i++) {
     double d = luaL_check_number(L, i);
     if (d > dmax)
       dmax = d;
   }
   lua_pushnumber(L, dmax);
+  return 1;
 }
 
 
-static void math_random (lua_State *L) {
+static int math_random (lua_State *L) {
   /* the '%' avoids the (rare) case of r==1, and is needed also because on
      some systems (SunOS!) "rand()" may return a value larger than RAND_MAX */
   double r = (double)(rand()%RAND_MAX) / (double)RAND_MAX;
-  if (lua_getparam(L, 1) == LUA_NOOBJECT)  /* no arguments? */
-    lua_pushnumber(L, r);  /* Number between 0 and 1 */
-  else {
-    int l, u;  /* lower & upper limits */
-    if (lua_getparam(L, 2) == LUA_NOOBJECT) {  /* only one argument? */
-      l = 1;
-      u = luaL_check_int(L, 1);
+  switch (lua_gettop(L)) {  /* check number of arguments */
+    case 0: {  /* no arguments */
+      lua_pushnumber(L, r);  /* Number between 0 and 1 */
+      break;
     }
-    else {  /* two arguments */
-      l = luaL_check_int(L, 1);
-      u = luaL_check_int(L, 2);
+    case 1: {  /* only upper limit */
+      int u = luaL_check_int(L, 1);
+      luaL_arg_check(L, 1<=u, 1, "interval is empty");
+      lua_pushnumber(L, (int)(r*u)+1);  /* integer between 1 and `u' */
+      break;
     }
-    luaL_arg_check(L, l<=u, 1, "interval is empty");
-    lua_pushnumber(L, (int)(r*(u-l+1))+l);  /* integer between `l' and `u' */
+    case 2: {  /* lower and upper limits */
+      int l = luaL_check_int(L, 1);
+      int u = luaL_check_int(L, 2);
+      luaL_arg_check(L, l<=u, 2, "interval is empty");
+      lua_pushnumber(L, (int)(r*(u-l+1))+l);  /* integer between `l' and `u' */
+      break;
+    }
+    default: lua_error(L, "wrong number of arguments");
   }
+  return 1;
 }
 
 
-static void math_randomseed (lua_State *L) {
+static int math_randomseed (lua_State *L) {
   srand(luaL_check_int(L, 1));
+  return 0;
 }
 
 
@@ -199,9 +230,10 @@ static const struct luaL_reg mathlib[] = {
 */
 void lua_mathlibopen (lua_State *L) {
   luaL_openl(L, mathlib);
-  lua_pushcfunction(L, math_pow);
   lua_pushnumber(L, 0);  /* to get its tag */
-  lua_settagmethod(L, lua_tag(L, lua_pop(L)), "pow");
+  lua_pushcfunction(L, math_pow);
+  lua_settagmethod(L, lua_tag(L, -2), "pow");
+  lua_settop(L, -1);  /* remove number */
   lua_pushnumber(L, PI); lua_setglobal(L, "PI");
 }
 

+ 0 - 118
lref.c

@@ -1,118 +0,0 @@
-/*
-** $Id: lref.c,v 1.17 2000/08/09 19:16:57 roberto Exp roberto $
-** reference mechanism
-** See Copyright Notice in lua.h
-*/
-
-
-#include "lua.h"
-
-#include "lapi.h"
-#include "ldo.h"
-#include "lmem.h"
-#include "lref.h"
-#include "lstate.h"
-
-
-int lua_ref (lua_State *L,  int lock) {
-  int ref;
-  luaA_checkCargs(L, 1);
-  if (ttype(L->top-1) == TAG_NIL)
-    ref = LUA_REFNIL;
-  else {
-    if (L->refFree != NONEXT) {  /* is there a free place? */
-      ref = L->refFree;
-      L->refFree = L->refArray[ref].st;
-    }
-    else {  /* no more free places */
-      luaM_growvector(L, L->refArray, L->refSize, 1, struct Ref,
-                      "reference table overflow", MAX_INT);
-      ref = L->refSize++;
-    }
-    L->refArray[ref].o = *(L->top-1);
-    L->refArray[ref].st = lock ? LOCK : HOLD;
-  }
-  L->top--;
-  return ref;
-}
-
-
-void lua_unref (lua_State *L, int ref) {
-  if (ref >= 0) {
-    if (ref >= L->refSize || L->refArray[ref].st >= 0)
-      lua_error(L, "Lua API error - "
-                   "invalid argument for function `lua_unref'");
-    L->refArray[ref].st = L->refFree;
-    L->refFree = ref;
-  }
-}
-
-
-int lua_pushref (lua_State *L, int ref) {
-  if (ref == LUA_REFNIL)
-    ttype(L->top) = TAG_NIL;
-  else if (0 <= ref && ref < L->refSize &&
-          (L->refArray[ref].st == LOCK || L->refArray[ref].st == HOLD))
-    *L->top = L->refArray[ref].o;
-  else
-    return 0;
-  incr_top;
-  return 1;
-}
-
-
-void lua_beginblock (lua_State *L) {
-  luaM_growvector(L, L->Cblocks, L->numCblocks, 1, struct C_Lua_Stack,
-                  "too many nested blocks", L->stacksize);
-  L->Cblocks[L->numCblocks] = L->Cstack;
-  L->numCblocks++;
-}
-
-
-void lua_endblock (lua_State *L) {
-  if (L->numCblocks <= 0)
-    lua_error(L, "Lua API error - no block to end");
-  --L->numCblocks;
-  L->Cstack = L->Cblocks[L->numCblocks];
-  L->top = L->Cstack.base;
-}
-
-
-
-
-
-
-static int hasmark (const TObject *o) {
-  /* valid only for locked objects */
-  switch (o->ttype) {
-    case TAG_STRING: case TAG_USERDATA:
-      return tsvalue(o)->marked;
-    case TAG_TABLE:
-      return ismarked(hvalue(o));
-    case TAG_LCLOSURE:  case TAG_CCLOSURE:
-      return ismarked(clvalue(o)->mark);
-    default:  /* number */
-      return 1;
-  }
-}
-
-
-/* for internal debugging only; check if a link of free refs is valid */
-#define VALIDLINK(L, st,n)	(NONEXT <= (st) && (st) < (n))
-
-void luaR_invalidaterefs (lua_State *L) {
-  int n = L->refSize;
-  int i;
-  for (i=0; i<n; i++) {
-    struct Ref *r = &L->refArray[i];
-    if (r->st == HOLD && !hasmark(&r->o))
-      r->st = COLLECTED;
-    LUA_ASSERT((r->st == LOCK && hasmark(&r->o)) ||
-                r->st == COLLECTED ||
-                r->st == NONEXT ||
-               (r->st < n && VALIDLINK(L, L->refArray[r->st].st, n)),
-               "inconsistent ref table");
-  }
-  LUA_ASSERT(VALIDLINK(L, L->refFree, n), "inconsistent ref table");
-}
-

+ 0 - 27
lref.h

@@ -1,27 +0,0 @@
-/*
-** $Id: lref.h,v 1.5 1999/12/27 17:33:22 roberto Exp roberto $
-** reference mechanism
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lref_h
-#define lref_h
-
-#include "lobject.h"
-
-
-#define NONEXT          -1      /* to end the free list */
-#define HOLD            -2
-#define COLLECTED       -3
-#define LOCK            -4
-
-
-struct Ref {
-  TObject o;
-  int st;  /* can be LOCK, HOLD, COLLECTED, or next (for free list) */
-};
-
-
-void luaR_invalidaterefs (lua_State *L);
-
-#endif

+ 1 - 7
lstate.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.c,v 1.32 2000/08/09 19:16:57 roberto Exp roberto $
+** $Id: lstate.c,v 1.33 2000/08/14 17:46:07 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -9,13 +9,11 @@
 
 #include "lua.h"
 
-#include "lauxlib.h"
 #include "lbuiltin.h"
 #include "ldo.h"
 #include "lgc.h"
 #include "llex.h"
 #include "lmem.h"
-#include "lref.h"
 #include "lstate.h"
 #include "lstring.h"
 #include "ltable.h"
@@ -35,8 +33,6 @@ lua_State *lua_newstate (int stacksize, int put_builtin) {
   L->Mbuffbase = 0;
   L->Mbuffsize = 0;
   L->Mbuffnext = 0;
-  L->Cblocks = NULL;
-  L->numCblocks = 0;
   L->rootproto = NULL;
   L->rootcl = NULL;
   L->roottable = NULL;
@@ -84,8 +80,6 @@ void lua_close (lua_State *L) {
   luaM_free(L, L->IMtable);
   luaM_free(L, L->refArray);
   luaM_free(L, L->Mbuffer);
-  luaM_free(L, L->Cblocks);
-  LUA_ASSERT(L->numCblocks == 0, "Cblocks still open");
   LUA_ASSERT(L->nblocks == 0, "wrong count for nblocks");
   luaM_free(L, L);
   LUA_ASSERT(L != lua_state || memdebug_numblocks == 0, "memory leak!");

+ 17 - 18
lstate.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.h,v 1.35 2000/08/07 18:39:16 roberto Exp roberto $
+** $Id: lstate.h,v 1.36 2000/08/08 20:42:07 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -19,27 +19,28 @@ typedef TObject *StkId;  /* index to stack elements */
 
 
 /*
-** chain list of long jumps
+** marks for Reference array
 */
-struct lua_longjmp {
-  jmp_buf b;
-  struct lua_longjmp *previous;
-  volatile int status;  /* error code */
-  StkId base;
-  int numCblocks;
+#define NONEXT          -1      /* to end the free list */
+#define HOLD            -2
+#define COLLECTED       -3
+#define LOCK            -4
+
+
+struct Ref {
+  TObject o;
+  int st;  /* can be LOCK, HOLD, COLLECTED, or next (for free list) */
 };
 
 
 /*
-** stack layout for C point of view:
-** [lua2C, lua2C+num) - `array' lua2C
-** [lua2C+num, base)  - space for extra lua_Objects (limbo)
-** [base, L->top)     - `stack' C2Lua
+** chain list of long jumps
 */
-struct C_Lua_Stack {
+struct lua_longjmp {
+  jmp_buf b;
+  struct lua_longjmp *previous;
+  volatile int status;  /* error code */
   StkId base;
-  StkId lua2C;
-  int num;
 };
 
 
@@ -57,14 +58,12 @@ struct lua_State {
   StkId stack;  /* stack base */
   StkId stack_last;  /* last free slot in the stack */
   int stacksize;
-  struct C_Lua_Stack Cstack;  /* C2lua struct */
+  StkId Cbase;  /* base for current C function */
   struct lua_longjmp *errorJmp;  /* current error recover point */
   char *Mbuffer;  /* global buffer */
   size_t Mbuffbase;  /* current first position of Mbuffer */
   size_t Mbuffsize;  /* size of Mbuffer */
   size_t Mbuffnext;  /* next position to fill in Mbuffer */
-  struct C_Lua_Stack *Cblocks;
-  int numCblocks;  /* number of nested Cblocks */
   /* global state */
   Proto *rootproto;  /* list of all prototypes */
   Closure *rootcl;  /* list of all closures */

+ 57 - 47
lstrlib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lstrlib.c,v 1.45 2000/06/12 14:37:18 roberto Exp roberto $
+** $Id: lstrlib.c,v 1.46 2000/08/09 19:16:57 roberto Exp roberto $
 ** Standard library for string operations and pattern-matching
 ** See Copyright Notice in lua.h
 */
@@ -25,10 +25,11 @@ static void addnchar (lua_State *L, const char *s, size_t n) {
 }
 
 
-static void str_len (lua_State *L) {
+static int str_len (lua_State *L) {
   size_t l;
   luaL_check_lstr(L, 1, &l);
   lua_pushnumber(L, l);
+  return 1;
 }
 
 
@@ -43,7 +44,7 @@ static long posrelat (long pos, size_t len) {
 }
 
 
-static void str_sub (lua_State *L) {
+static int str_sub (lua_State *L) {
   size_t l;
   const char *s = luaL_check_lstr(L, 1, &l);
   long start = posrelat(luaL_check_long(L, 2), l);
@@ -53,10 +54,11 @@ static void str_sub (lua_State *L) {
   if (start <= end)
     lua_pushlstring(L, s+start-1, end-start+1);
   else lua_pushstring(L, "");
+  return 1;
 }
 
 
-static void str_lower (lua_State *L) {
+static int str_lower (lua_State *L) {
   size_t l;
   size_t i;
   const char *s = luaL_check_lstr(L, 1, &l);
@@ -64,10 +66,11 @@ static void str_lower (lua_State *L) {
   for (i=0; i<l; i++)
     luaL_addchar(L, tolower((unsigned char)(s[i])));
   closeandpush(L);
+  return 1;
 }
 
 
-static void str_upper (lua_State *L) {
+static int str_upper (lua_State *L) {
   size_t l;
   size_t i;
   const char *s = luaL_check_lstr(L, 1, &l);
@@ -75,9 +78,10 @@ static void str_upper (lua_State *L) {
   for (i=0; i<l; i++)
     luaL_addchar(L, toupper((unsigned char)(s[i])));
   closeandpush(L);
+  return 1;
 }
 
-static void str_rep (lua_State *L) {
+static int str_rep (lua_State *L) {
   size_t l;
   const char *s = luaL_check_lstr(L, 1, &l);
   int n = luaL_check_int(L, 2);
@@ -85,27 +89,31 @@ static void str_rep (lua_State *L) {
   while (n-- > 0)
     addnchar(L, s, l);
   closeandpush(L);
+  return 1;
 }
 
 
-static void str_byte (lua_State *L) {
+static int str_byte (lua_State *L) {
   size_t l;
   const char *s = luaL_check_lstr(L, 1, &l);
   long pos = posrelat(luaL_opt_long(L, 2, 1), l);
   luaL_arg_check(L, 0<pos && (size_t)pos<=l, 2,  "out of range");
   lua_pushnumber(L, (unsigned char)s[pos-1]);
+  return 1;
 }
 
 
-static void str_char (lua_State *L) {
-  int i = 0;
+static int str_char (lua_State *L) {
+  int n = lua_gettop(L);  /* number of arguments */
+  int i;
   luaL_resetbuffer(L);
-  while (lua_getparam(L, ++i) != LUA_NOOBJECT) {
+  for (i=1; i<=n; i++) {
     int c = luaL_check_int(L, i);
     luaL_arg_check(L, (unsigned char)c == c, i, "invalid value");
     luaL_addchar(L, (unsigned char)c);
   }
   closeandpush(L);
+  return 1;
 }
 
 
@@ -135,16 +143,6 @@ struct Capture {
 #define SPECIALS	"^$*+?.([%-"
 
 
-static void push_captures (lua_State *L, struct Capture *cap) {
-  int i;
-  for (i=0; i<cap->level; i++) {
-    int l = cap->capture[i].len;
-    if (l == -1) lua_error(L, "unfinished capture");
-    lua_pushlstring(L, cap->capture[i].init, l);
-  }
-}
-
-
 static int check_capture (lua_State *L, int l, struct Capture *cap) {
   l -= '1';
   if (!(0 <= l && l < cap->level && cap->capture[l].len != -1))
@@ -400,20 +398,31 @@ static const char *lmemfind (const char *s1, size_t l1,
 }
 
 
-static void str_find (lua_State *L) {
+static int push_captures (lua_State *L, struct Capture *cap) {
+  int i;
+  for (i=0; i<cap->level; i++) {
+    int l = cap->capture[i].len;
+    if (l == -1) lua_error(L, "unfinished capture");
+    lua_pushlstring(L, cap->capture[i].init, l);
+  }
+  return cap->level;  /* number of strings pushed */
+}
+
+
+static int str_find (lua_State *L) {
   size_t l1, l2;
   const char *s = luaL_check_lstr(L, 1, &l1);
   const char *p = luaL_check_lstr(L, 2, &l2);
   long init = posrelat(luaL_opt_long(L, 3, 1), l1) - 1;
   struct Capture cap;
   luaL_arg_check(L, 0 <= init && (size_t)init <= l1, 3, "out of range");
-  if (lua_getparam(L, 4) != LUA_NOOBJECT ||
-      strpbrk(p, SPECIALS) == NULL) {  /* no special characters? */
+  if (lua_gettop(L) > 3 ||  /* extra argument? */
+      strpbrk(p, SPECIALS) == NULL) {  /* or no special characters? */
     const char *s2 = lmemfind(s+init, l1-init, p, l2);
     if (s2) {
       lua_pushnumber(L, s2-s+1);
       lua_pushnumber(L, s2-s+l2);
-      return;
+      return 2;
     }
   }
   else {
@@ -426,19 +435,19 @@ static void str_find (lua_State *L) {
       if ((res=match(L, s1, p, &cap)) != NULL) {
         lua_pushnumber(L, s1-s+1);  /* start */
         lua_pushnumber(L, res-s);   /* end */
-        push_captures(L, &cap);
-        return;
+        return push_captures(L, &cap) + 2;
       }
     } while (s1++<cap.src_end && !anchor);
   }
   lua_pushnil(L);  /* not found */
+  return 1;
 }
 
 
-static void add_s (lua_State *L, lua_Object newp, struct Capture *cap) {
-  if (lua_isstring(L, newp)) {
-    const char *news = lua_getstring(L, newp);
-    size_t l = lua_strlen(L, newp);
+static void add_s (lua_State *L, struct Capture *cap) {
+  if (lua_isstring(L, 3)) {
+    const char *news = lua_tostring(L, 3);
+    size_t l = lua_strlen(L, 3);
     size_t i;
     for (i=0; i<l; i++) {
       if (news[i] != ESC)
@@ -455,39 +464,38 @@ static void add_s (lua_State *L, lua_Object newp, struct Capture *cap) {
     }
   }
   else {  /* is a function */
-    lua_Object res;
     int status;
     size_t oldbuff;
-    lua_beginblock(L);
-    push_captures(L, cap);
+    int n;
+    const char *s;
+    lua_pushobject(L, 3);
+    n = push_captures(L, cap);
     /* function may use buffer, so save it and create a new one */
     oldbuff = luaL_newbuffer(L, 0);
-    status = lua_callfunction(L, newp);
+    status = lua_call(L, n, 1);
     /* restore old buffer */
     luaL_oldbuffer(L, oldbuff);
-    if (status != 0) {
-      lua_endblock(L);
+    if (status != 0)
       lua_error(L, NULL);
-    }
-    res = lua_getresult(L, 1);
-    if (lua_isstring(L, res))
-      addnchar(L, lua_getstring(L, res), lua_strlen(L, res));
-    lua_endblock(L);
+    s = lua_tostring(L, -1);
+    if (s)
+      addnchar(L, lua_tostring(L, -1), lua_strlen(L, -1));
+    lua_settop(L, -1);  /* pop function result */
   }
 }
 
 
-static void str_gsub (lua_State *L) {
+static int str_gsub (lua_State *L) {
   size_t srcl;
   const char *src = luaL_check_lstr(L, 1, &srcl);
   const char *p = luaL_check_string(L, 2);
-  lua_Object newp = lua_getparam(L, 3);
   int max_s = luaL_opt_int(L, 4, srcl+1);
   int anchor = (*p == '^') ? (p++, 1) : 0;
   int n = 0;
   struct Capture cap;
-  luaL_arg_check(L, lua_isstring(L, newp) || lua_isfunction(L, newp), 3,
-                 "string or function expected");
+  luaL_arg_check(L,
+    lua_gettop(L) >= 3 && (lua_isstring(L, 3) || lua_isfunction(L, 3)),
+    3, "string or function expected");
   luaL_resetbuffer(L);
   cap.src_end = src+srcl;
   while (n < max_s) {
@@ -496,7 +504,7 @@ static void str_gsub (lua_State *L) {
     e = match(L, src, p, &cap);
     if (e) {
       n++;
-      add_s(L, newp, &cap);
+      add_s(L, &cap);
     }
     if (e && e>src) /* non empty match? */
       src = e;  /* skip it */
@@ -508,6 +516,7 @@ static void str_gsub (lua_State *L) {
   addnchar(L, src, cap.src_end-src);
   closeandpush(L);
   lua_pushnumber(L, n);  /* number of substitutions */
+  return 2;
 }
 
 /* }====================================================== */
@@ -534,7 +543,7 @@ static void luaI_addquoted (lua_State *L, int arg) {
 /* maximum size of each format specification (such as '%-099.99d') */
 #define MAX_FORMAT 20  /* arbitrary limit */
 
-static void str_format (lua_State *L) {
+static int str_format (lua_State *L) {
   int arg = 1;
   const char *strfrmt = luaL_check_string(L, arg);
   luaL_resetbuffer(L);
@@ -597,6 +606,7 @@ static void str_format (lua_State *L) {
     }
   }
   closeandpush(L);  /* push the result */
+  return 1;
 }
 
 

+ 213 - 200
ltests.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltests.c,v 1.33 2000/08/09 19:16:57 roberto Exp roberto $
+** $Id: ltests.c,v 1.34 2000/08/15 20:14:27 roberto Exp roberto $
 ** Internal Module for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 */
@@ -10,7 +10,6 @@
 #include <stdlib.h>
 #include <string.h>
 
-#define LUA_SINGLESTATE
 
 #include "lua.h"
 
@@ -38,11 +37,11 @@ void luaB_opentests (lua_State *L);
 
 
 
-static void setnameval (lua_Object t, const char *name, int val) {
-  lua_pushobject(t);
-  lua_pushstring(name);
-  lua_pushnumber(val);
-  lua_settable();
+static void setnameval (lua_State *L, const char *name, int val) {
+  lua_pushobject(L, -1);
+  lua_pushstring(L, name);
+  lua_pushnumber(L, val);
+  lua_settable(L);
 }
 
 
@@ -65,7 +64,7 @@ static const char *const instrname[NUM_OPCODES] = {
 };
 
 
-static int pushop (Proto *p, int pc) {
+static int pushop (lua_State *L, Proto *p, int pc) {
   char buff[100];
   Instruction i = p->code[pc];
   OpCode o = GET_OPCODE(i);
@@ -85,146 +84,161 @@ static int pushop (Proto *p, int pc) {
       sprintf(buff+8, "%-12s%4d %4d", name, GETARG_A(i), GETARG_B(i));
       break;
   }
-  lua_pushstring(buff);
+  lua_pushstring(L, buff);
   return (o != OP_END);
 }
 
 
-static void listcode (void) {
-  lua_Object o = luaL_nonnullarg(1);
-  lua_Object t = lua_createtable();
+static int listcode (lua_State *L) {
   int pc;
   Proto *p;
   int res;
-  luaL_arg_check(ttype(o) == TAG_LCLOSURE, 1, "Lua function expected");
-  p = clvalue(o)->f.l;
-  setnameval(t, "maxstack", p->maxstacksize);
-  setnameval(t, "numparams", p->numparams);
+  luaL_arg_check(L, lua_tag(L, 1) == TAG_LCLOSURE, 1, "Lua function expected");
+  p = clvalue(luaA_index(L, 1))->f.l;
+  lua_newtable(L);
+  setnameval(L, "maxstack", p->maxstacksize);
+  setnameval(L, "numparams", p->numparams);
   pc = 0;
   do {
-    lua_pushobject(t);
-    lua_pushnumber(pc+1);
-    res = pushop(p, pc++);
-    lua_settable();
+    lua_pushobject(L, -1);
+    lua_pushnumber(L, pc+1);
+    res = pushop(L, p, pc++);
+    lua_settable(L);
   } while (res);
-  lua_pushobject(t);
+  return 1;
 }
 
 
-static void liststrings (void) {
-  lua_Object o = luaL_nonnullarg(1);
-  lua_Object t = lua_createtable();
+static int liststrings (lua_State *L) {
   Proto *p;
   int i;
-  luaL_arg_check(ttype(o) == TAG_LCLOSURE, 1, "Lua function expected");
-  p = clvalue(o)->f.l;
+  luaL_arg_check(L, lua_tag(L, 1) == TAG_LCLOSURE, 1, "Lua function expected");
+  p = clvalue(luaA_index(L, 1))->f.l;
+  lua_newtable(L);
   for (i=0; i<p->nkstr; i++) {
-    lua_pushobject(t);
-    lua_pushnumber(i+1);
-    lua_pushstring(p->kstr[i]->str);
-    lua_settable();
+    lua_pushobject(L, -1);
+    lua_pushnumber(L, i+1);
+    lua_pushstring(L, p->kstr[i]->str);
+    lua_settable(L);
   }
-  lua_pushobject(t);
+  return 1;
 }
 
 
-static void listlocals (void) {
-  lua_Object o = luaL_nonnullarg(1);
+static int listlocals (lua_State *L) {
   Proto *p;
-  int pc = luaL_check_int(2) - 1;
-  int i = 1;
+  int pc = luaL_check_int(L, 2) - 1;
+  int i = 0;
   const char *name;
-  luaL_arg_check(ttype(o) == TAG_LCLOSURE, 1, "Lua function expected");
-  p = clvalue(o)->f.l;
-  while ((name = luaF_getlocalname(p, i++, pc)) != NULL)
-    lua_pushstring(name);
+  luaL_arg_check(L, lua_tag(L, 1) == TAG_LCLOSURE, 1, "Lua function expected");
+  p = clvalue(luaA_index(L, 1))->f.l;
+  while ((name = luaF_getlocalname(p, ++i, pc)) != NULL)
+    lua_pushstring(L, name);
+  return i-1;
 }
 
 /* }====================================================== */
 
 
 
-static void get_limits (void) {
-  lua_Object t = lua_createtable();
-  setnameval(t, "BITS_INT", BITS_INT);
-  setnameval(t, "LFPF", LFIELDS_PER_FLUSH);
-  setnameval(t, "MAXARG_A", MAXARG_A);
-  setnameval(t, "MAXARG_B", MAXARG_B);
-  setnameval(t, "MAXARG_S", MAXARG_S);
-  setnameval(t, "MAXARG_U", MAXARG_U);
-  setnameval(t, "MAXLOCALS", MAXLOCALS);
-  setnameval(t, "MAXPARAMS", MAXPARAMS);
-  setnameval(t, "MAXSTACK", MAXSTACK);
-  setnameval(t, "MAXUPVALUES", MAXUPVALUES);
-  setnameval(t, "MAXVARSLH", MAXVARSLH);
-  setnameval(t, "RFPF", RFIELDS_PER_FLUSH);
-  setnameval(t, "SIZE_A", SIZE_A);
-  setnameval(t, "SIZE_B", SIZE_B);
-  setnameval(t, "SIZE_OP", SIZE_OP);
-  setnameval(t, "SIZE_U", SIZE_U);
-  lua_pushobject(t);
+static int get_limits (lua_State *L) {
+  lua_newtable(L);
+  setnameval(L, "BITS_INT", BITS_INT);
+  setnameval(L, "LFPF", LFIELDS_PER_FLUSH);
+  setnameval(L, "MAXARG_A", MAXARG_A);
+  setnameval(L, "MAXARG_B", MAXARG_B);
+  setnameval(L, "MAXARG_S", MAXARG_S);
+  setnameval(L, "MAXARG_U", MAXARG_U);
+  setnameval(L, "MAXLOCALS", MAXLOCALS);
+  setnameval(L, "MAXPARAMS", MAXPARAMS);
+  setnameval(L, "MAXSTACK", MAXSTACK);
+  setnameval(L, "MAXUPVALUES", MAXUPVALUES);
+  setnameval(L, "MAXVARSLH", MAXVARSLH);
+  setnameval(L, "RFPF", RFIELDS_PER_FLUSH);
+  setnameval(L, "SIZE_A", SIZE_A);
+  setnameval(L, "SIZE_B", SIZE_B);
+  setnameval(L, "SIZE_OP", SIZE_OP);
+  setnameval(L, "SIZE_U", SIZE_U);
+  return 1;
 }
 
 
-static void mem_query (void) {
-  lua_Object arg = lua_getparam(1);
-  if (arg == LUA_NOOBJECT) {
-    lua_pushnumber(memdebug_total);
-    lua_pushnumber(memdebug_numblocks);
-    lua_pushnumber(memdebug_maxmem);
+static int mem_query (lua_State *L) {
+  if (lua_isnull(L, 1)) {
+    lua_pushnumber(L, memdebug_total);
+    lua_pushnumber(L, memdebug_numblocks);
+    lua_pushnumber(L, memdebug_maxmem);
+    return 3;
+  }
+  else {
+    memdebug_memlimit = luaL_check_int(L, 1);
+    return 0;
   }
-  else
-    memdebug_memlimit = luaL_check_int(1);
 }
 
 
-static void hash_query (void) {
-  lua_Object o = luaL_nonnullarg(1);
-  if (lua_getparam(2) == LUA_NOOBJECT) {
-    luaL_arg_check(ttype(o) == TAG_STRING, 1, "string expected");
-    lua_pushnumber(tsvalue(o)->u.s.hash);
+static int hash_query (lua_State *L) {
+  if (lua_isnull(L, 2)) {
+    luaL_arg_check(L, lua_tag(L, 1) == TAG_STRING, 1, "string expected");
+    lua_pushnumber(L, tsvalue(luaA_index(L, 1))->u.s.hash);
   }
   else {
-    const Hash *t = hvalue(luaL_tablearg(2));
-    lua_pushnumber(luaH_mainposition(t, o) - t->node);
+    Hash *t;
+    luaL_checktype(L, 2, "table");
+    t = hvalue(luaA_index(L, 2));
+    lua_pushnumber(L, luaH_mainposition(t, luaA_index(L, 1)) - t->node);
   }
+  return 1;
 }
 
 
-static void table_query (void) {
-  const Hash *t = hvalue(luaL_tablearg(1));
-  int i = luaL_opt_int(2, -1);
+static int table_query (lua_State *L) {
+  const Hash *t;
+  int i = luaL_opt_int(L, 2, -1);
+  luaL_checktype(L, 1, "table");
+  t = hvalue(luaA_index(L, 1));
   if (i == -1) {
-    lua_pushnumber(t->size);
-    lua_pushnumber(t->firstfree - t->node);
+    lua_pushnumber(L, t->size);
+    lua_pushnumber(L, t->firstfree - t->node);
+    return 2;
   }
   else if (i < t->size) {
-    luaA_pushobject(lua_state, &t->node[i].key);
-    luaA_pushobject(lua_state, &t->node[i].val);
-    if (t->node[i].next)
-      lua_pushnumber(t->node[i].next - t->node);
+    luaA_pushobject(L, &t->node[i].key);
+    luaA_pushobject(L, &t->node[i].val);
+    if (t->node[i].next) {
+      lua_pushnumber(L, t->node[i].next - t->node);
+      return 3;
+    }
+    else
+      return 2;
   }
+  return 0;
 }
 
 
-static void string_query (void) {
-  lua_State *L = lua_state;
-  stringtable *tb = (*luaL_check_string(1) == 's') ? &L->strt : &L->udt;
-  int s = luaL_opt_int(2, 0) - 1;
+static int string_query (lua_State *L) {
+  stringtable *tb = (*luaL_check_string(L, 1) == 's') ? &L->strt : &L->udt;
+  int s = luaL_opt_int(L, 2, 0) - 1;
   if (s==-1) {
-    lua_pushnumber(tb->nuse);
-    lua_pushnumber(tb->size);
+    lua_pushnumber(L ,tb->nuse);
+    lua_pushnumber(L ,tb->size);
+    return 2;
   }
   else if (s < tb->size) {
     TString *ts;
+    int n = 0;
     for (ts = tb->hash[s]; ts; ts = ts->nexthash) {
       ttype(L->top) = TAG_STRING;
       tsvalue(L->top) = ts;
       incr_top;
+      n++;
     }
+    return n;
   }
+  return 0;
 }
 
+
 /*
 ** {======================================================
 ** function to test the API with C. It interprets a kind of "assembler"
@@ -238,21 +252,33 @@ static void skip (const char **pc) {
   while (**pc != '\0' && strchr(delimits, **pc)) (*pc)++;
 }
 
-static int getnum (const char **pc) {
+static int getnum (const char **pc, int *reg) {
   int res = 0;
+  int sig = 1;
+  int ref = 0;
   skip(pc);
+  if (**pc == 'r') {
+    ref = 1;
+    (*pc)++;
+  }
+  else if (**pc == '-') {
+    sig = -1;
+    (*pc)++;
+  }
   while (isdigit(**pc)) res = res*10 + (*(*pc)++) - '0';
-  return res;
+  if (!ref)
+    return sig*res;
+  else
+    return reg[res];
 }
   
 static int getreg (const char **pc) {
   skip(pc);
-  if (*(*pc)++ != 'r') lua_error("`testC' expecting a register");
-  return getnum(pc);
+  (*pc)++;  /* skip the `r' */
+  return getnum(pc, NULL);
 }
 
-static const char *getname (const char **pc) {
-  static char buff[30];
+static const char *getname (char *buff, const char **pc) {
   int i = 0;
   skip(pc);
   while (**pc != '\0' && !strchr(delimits, **pc))
@@ -264,159 +290,148 @@ static const char *getname (const char **pc) {
 
 #define EQ(s1)	(strcmp(s1, inst) == 0)
 
+#define getnum	((getnum)(&pc, reg))
+#define getreg	((getreg)(&pc))
+#define getname	((getname)(buff, &pc))
+
 
-static void testC (void) {
-  lua_Object reg[10];
-  const char *pc = luaL_check_string(1);
+static int testC (lua_State *L) {
+  char buff[30];
+  int reg[10];
+  const char *pc = luaL_check_string(L, 1);
   for (;;) {
-    const char *inst = getname(&pc);
-    if EQ("") return;
+    const char *inst = getname;
+    if EQ("") return 0;
+    else if EQ("return") {
+      return getnum;
+    }
+    else if EQ("retall") {
+      return lua_gettop(L) - 1;
+    }
+    else if EQ("gettop") {
+      reg[getreg] = lua_gettop(L);
+    }
+    else if EQ("settop") {
+      lua_settop(L, getnum);
+    }
+    else if EQ("setreg") {
+      int n = getreg;
+      reg[n] = lua_tonumber(L, getnum);
+    }
     else if EQ("pushnum") {
-      lua_pushnumber(getnum(&pc));
+      lua_pushnumber(L, getnum);
     }
-    else if EQ("createtable") {
-      reg[getreg(&pc)] = lua_createtable();
+    else if EQ("newtable") {
+      lua_newtable(L);
     }
     else if EQ("closure") {
-      lua_CFunction f = lua_getcfunction(lua_getglobal(getname(&pc)));
-      lua_pushcclosure(f, getnum(&pc));
+      lua_CFunction f;
+      lua_getglobal(L, getname);
+      f = lua_tocfunction(L, -1);
+      lua_settop(L, -1);
+      lua_pushcclosure(L, f, getnum);
     }
-    else if EQ("pop") {
-      reg[getreg(&pc)] = lua_pop();
+    else if EQ("pushobject") {
+      lua_pushobject(L, getnum);
     }
     else if EQ("getglobal") {
-      int n = getreg(&pc);
-      reg[n] = lua_getglobal(getname(&pc));
+      lua_getglobal(L, getname);
     }
     else if EQ("ref") {
-      lua_pushnumber(lua_ref(0));
-      reg[getreg(&pc)] = lua_pop();
+      reg[getreg] = lua_ref(L, 0);
     }
     else if EQ("reflock") {
-      lua_pushnumber(lua_ref(1));
-      reg[getreg(&pc)] = lua_pop();
+      reg[getreg] = lua_ref(L, 1);
     }
     else if EQ("getref") {
-      int n = getreg(&pc);
-      reg[n] = lua_getref((int)lua_getnumber(reg[getreg(&pc)]));
+      int n = getreg;
+      reg[n] = lua_getref(L, getnum);
     }
     else if EQ("unref") {
-      lua_unref((int)lua_getnumber(reg[getreg(&pc)]));
-    }
-    else if EQ("getparam") {
-      int n = getreg(&pc);
-      reg[n] = lua_getparam(getnum(&pc)+1);  /* skips the command itself */
-    }
-    else if EQ("getresult") {
-      int n = getreg(&pc);
-      reg[n] = lua_getparam(getnum(&pc));
+      lua_unref(L, getnum);
     }
     else if EQ("setglobal") {
-      lua_setglobal(getname(&pc));
-    }
-    else if EQ("pushglobals") {
-      lua_pushglobals();
+      lua_setglobal(L, getname);
     }
     else if EQ("pushstring") {
-      lua_pushstring(getname(&pc));
-    }
-    else if EQ("pushreg") {
-      lua_pushobject(reg[getreg(&pc)]);
+      lua_pushstring(L, getname);
     }
     else if EQ("call") {
-      if (lua_call(getname(&pc))) lua_error(NULL);
+      int narg = getnum;
+      int nres = getnum;
+      if (lua_call(L, narg, nres)) lua_error(L, NULL);
     }
     else if EQ("gettable") {
-      reg[getreg(&pc)] = lua_gettable();
+      lua_gettable(L);
     }
     else if EQ("rawget") {
-      reg[getreg(&pc)] = lua_rawget();
+      lua_rawget(L);
     }
     else if EQ("settable") {
-      lua_settable();
+      lua_settable(L);
     }
     else if EQ("rawset") {
-      lua_rawset();
+      lua_rawset(L);
     }
     else if EQ("tag") {
-      lua_pushnumber(lua_tag(reg[getreg(&pc)]));
+      int n = getreg;
+      reg[n] = lua_tag(L, getnum);
     }
     else if EQ("type") {
-      lua_pushstring(lua_type(reg[getreg(&pc)]));
-    }
-    else if EQ("next") {
-      int n = getreg(&pc);
-      n = lua_next(reg[n], (int)lua_getnumber(reg[getreg(&pc)]));
-      lua_pushnumber(n);
+      lua_pushstring(L, lua_type(L, getnum));
     }
     else if EQ("equal") {
-      int n1 = getreg(&pc);
-      int n2 = getreg(&pc);
-      lua_pushnumber(lua_equal(reg[n1], reg[n2]));
+      int n1 = getreg;
+      int n2 = getnum;
+      int n3 = getnum;
+      reg[n1] = lua_equal(L, n2, n3);
     }
     else if EQ("pushusertag") {
-      int val = getreg(&pc);
-      int tag = getreg(&pc);
-      lua_pushusertag((void *)(int)lua_getnumber(reg[val]),
-                         (int)lua_getnumber(reg[tag]));
+      int val = getnum;
+      int tag = getnum;
+      lua_pushusertag(L, (void *)val, tag);
     }
     else if EQ("udataval") {
-      int n = getreg(&pc);
-      lua_pushnumber((int)lua_getuserdata(reg[getreg(&pc)]));
-      reg[n] = lua_pop();
+      int n = getreg;
+      reg[n] = (int)lua_touserdata(L, getnum);
     }
     else if EQ("settagmethod") {
-      int n = getreg(&pc);
-      lua_settagmethod((int)lua_getnumber(reg[n]), getname(&pc));
-    }
-    else if EQ("beginblock") {
-      lua_beginblock();
-    }
-    else if EQ("endblock") {
-      lua_endblock();
+      int n = getnum;
+      lua_settagmethod(L, n, getname);
     }
     else if EQ("newstate") {
-      int stacksize = getnum(&pc);
-      lua_State *L1 = lua_newstate(stacksize, getnum(&pc));
+      int stacksize = getnum;
+      lua_State *L1 = lua_newstate(stacksize, getnum);
       if (L1)
-        lua_pushuserdata(L1);
+        lua_pushuserdata(L, L1);
       else
-        lua_pushnil();
+        lua_pushnil(L);
     }
     else if EQ("closestate") {
-      (lua_close)((lua_State *)lua_getuserdata(reg[getreg(&pc)]));
+      (lua_close)((lua_State *)lua_touserdata(L, getnum));
     }
     else if EQ("doremote") {
-      lua_Object ol1 = reg[getreg(&pc)];
-      lua_Object str = reg[getreg(&pc)];
+      int ol1 = getnum;
+      int str = getnum;
       lua_State *L1;
-      lua_Object temp;
       int status;
-      if (!lua_isuserdata(ol1) || !lua_isstring(str))
-        lua_error("bad arguments for `doremote'");
-      L1 = (lua_State *)lua_getuserdata(ol1);
-      status = (lua_dostring)(L1, lua_getstring(str));
+      if (!lua_isuserdata(L, ol1) || !lua_isstring(L, str))
+        lua_error(L, "bad arguments for `doremote'");
+      L1 = (lua_State *)lua_touserdata(L, ol1);
+      status = lua_dostring(L1, lua_tostring(L, str));
       if (status != 0) {
-        lua_pushnil();
-        lua_pushnumber(status);
+        lua_pushnil(L);
+        lua_pushnumber(L, status);
       }
       else {
-        int i = 1;
-        while ((temp = (lua_getresult)(L1, i++)) != LUA_NOOBJECT)
-          lua_pushstring((lua_getstring)(L1, temp));
+        int i = 0;
+        while (!lua_isnull(L, ++i))
+          lua_pushstring(L, lua_tostring(L1, i));
       }
     }
-#if LUA_DEPRECATETFUNCS
-    else if EQ("rawsetglobal") {
-      lua_rawsetglobal(getname(&pc));
-    }
-    else if EQ("rawgetglobal") {
-      int n = getreg(&pc);
-      reg[n] = lua_rawgetglobal(getname(&pc));
-    }
-#endif
-    else luaL_verror(lua_state, "unknown command in `testC': %.20s", inst);
+    else luaL_verror(L, "unknown instruction %.30s", buff);
   }
+  return 0;
 }
 
 /* }====================================================== */
@@ -424,22 +439,20 @@ static void testC (void) {
 
 
 static const struct luaL_reg tests_funcs[] = {
-  {"hash", (lua_CFunction)hash_query},
-  {"limits", (lua_CFunction)get_limits},
-  {"listcode", (lua_CFunction)listcode},
-  {"liststrings", (lua_CFunction)liststrings},
-  {"listlocals", (lua_CFunction)listlocals},
-  {"querystr", (lua_CFunction)string_query},
-  {"querytab", (lua_CFunction)table_query},
-  {"testC", (lua_CFunction)testC},
-  {"totalmem", (lua_CFunction)mem_query}
+  {"hash", hash_query},
+  {"limits", get_limits},
+  {"listcode", listcode},
+  {"liststrings", liststrings},
+  {"listlocals", listlocals},
+  {"querystr", string_query},
+  {"querytab", table_query},
+  {"testC", testC},
+  {"totalmem", mem_query}
 };
 
 
 void luaB_opentests (lua_State *L) {
-  if (lua_state != NULL) return;  /* do not open tests for auxiliar states */
-  lua_state = L;
-  luaL_openl(tests_funcs);
+  luaL_openl(L, tests_funcs);
 }
 
 #endif

+ 38 - 36
lua.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lua.c,v 1.44 2000/08/09 19:16:57 roberto Exp roberto $
+** $Id: lua.c,v 1.45 2000/08/14 17:45:59 roberto Exp roberto $
 ** Lua stand-alone interpreter
 ** See Copyright Notice in lua.h
 */
@@ -10,14 +10,14 @@
 #include <stdlib.h>
 #include <string.h>
 
-#define LUA_SINGLESTATE
-
 #include "lua.h"
 
 #include "luadebug.h"
 #include "lualib.h"
 
+
 lua_State *lua_state = NULL;
+#define L	lua_state
 
 
 #ifndef PROMPT
@@ -54,10 +54,10 @@ extern void USERINIT (void);
 #else
 #define USERINIT	userinit
 static void userinit (void) {
-  lua_iolibopen();
-  lua_strlibopen();
-  lua_mathlibopen();
-  lua_dblibopen();
+  lua_iolibopen(L);
+  lua_strlibopen(L);
+  lua_mathlibopen(L);
+  lua_dblibopen(L);
 }
 #endif
 
@@ -68,10 +68,10 @@ static handler lreset (void) {
 
 
 static void lstop (void) {
-  lua_setlinehook(lua_state, old_linehook);
-  lua_setcallhook(lua_state, old_callhook);
+  lua_setlinehook(L, old_linehook);
+  lua_setcallhook(L, old_callhook);
   lreset();
-  lua_error("interrupted!");
+  lua_error(L, "interrupted!");
 }
 
 
@@ -79,15 +79,15 @@ static void laction (int i) {
   (void)i;  /* to avoid warnings */
   signal(SIGINT, SIG_DFL); /* if another SIGINT happens before lstop,
                               terminate process (default action) */
-  old_linehook = lua_setlinehook(lua_state, (lua_Hook)lstop);
-  old_callhook = lua_setcallhook(lua_state, (lua_Hook)lstop);
+  old_linehook = lua_setlinehook(L, (lua_Hook)lstop);
+  old_callhook = lua_setcallhook(L, (lua_Hook)lstop);
 }
 
 
-static int ldo (int (*f)(lua_State *L, const char *), const char *name) {
+static int ldo (int (*f)(lua_State *l, const char *), const char *name) {
   int res;
   handler h = lreset();
-  res = f(lua_state, name);  /* dostring | dofile */
+  res = f(L, name);  /* dostring | dofile */
   signal(SIGINT, h);  /* restore old action */
   if (res == LUA_ERRMEM) {
     /* Lua gives no message in such case, so lua.c provides one */
@@ -122,29 +122,29 @@ static void print_version (void) {
 static void assign (char *arg) {
   char *eq = strchr(arg, '=');
   *eq = '\0';  /* spilt `arg' in two strings (name & value) */
-  lua_pushstring(eq+1);
-  lua_setglobal(arg);
+  lua_pushstring(L, eq+1);
+  lua_setglobal(L, arg);
 }
 
 
-static lua_Object getargs (char *argv[]) {
-  lua_Object args = lua_createtable();
+static void getargs (char *argv[]) {
   int i;
+  lua_newtable(L);
   for (i=0; argv[i]; i++) {
     /* arg[i] = argv[i] */
-    lua_pushobject(args); lua_pushnumber(i);
-    lua_pushstring(argv[i]); lua_settable();
+    lua_pushobject(L, -1); lua_pushnumber(L, i);
+    lua_pushstring(L, argv[i]); lua_settable(L);
   }
   /* arg.n = maximum index in table `arg' */
-  lua_pushobject(args); lua_pushstring("n");
-  lua_pushnumber(i-1); lua_settable();
-  return args;
+  lua_pushobject(L, -1); lua_pushstring(L, "n");
+  lua_pushnumber(L, i-1); lua_settable(L);
 }
 
 
-static void l_getargs (void) {
-  char **argv = (char **)lua_getuserdata(lua_getparam(1));
-  lua_pushobject(getargs(argv));
+static int l_getargs (lua_State *l) {
+  char **argv = (char **)lua_touserdata(l, 1);
+  getargs(argv);
+  return 1;
 }
 
 
@@ -173,9 +173,11 @@ static void manual_input (int version, int prompt) {
   while (cont) {
     char buffer[MAXINPUT];
     int i = 0;
-    lua_beginblock();
     if (prompt) {
-      const char *s = lua_getstring(lua_getglobal("_PROMPT"));
+      const char *s;
+      lua_getglobal(L, "_PROMPT");
+      s = lua_tostring(L, -1);
+      lua_settop(L, -1);  /* remove global */
       if (!s) s = PROMPT;
       fputs(s, stdout);
     }
@@ -198,7 +200,7 @@ static void manual_input (int version, int prompt) {
     }
     buffer[i] = '\0';
     ldo(lua_dostring, buffer);
-    lua_endblock();
+    lua_settop(L, 0);  /* remove eventual results */
   }
   printf("\n");
 }
@@ -262,8 +264,8 @@ static int handle_argv (char *argv[], struct Options *opt) {
               print_message();
               return EXIT_FAILURE;
             }
-            lua_pushobject(getargs(argv+i));  /* collect remaining arguments */
-            lua_setglobal("arg");
+            getargs(argv+i);  /* collect remaining arguments */
+            lua_setglobal(L, "arg");
             return file_input(argv[i]);  /* stop scanning arguments */
           }
           case 's': {
@@ -296,9 +298,9 @@ static void getstacksize (int argc, char *argv[], struct Options *opt) {
 
 
 static void register_getargs (char *argv[]) {
-  lua_pushuserdata(argv);
-  lua_pushcclosure(l_getargs, 1);
-  lua_setglobal("getargs");
+  lua_pushuserdata(L, argv);
+  lua_pushcclosure(L, l_getargs, 1);
+  lua_setglobal(L, "getargs");
 }
 
 
@@ -307,12 +309,12 @@ int main (int argc, char *argv[]) {
   int status;
   opt.toclose = 0;
   getstacksize(argc, argv, &opt);  /* handle option `-s' */
-  lua_state = lua_newstate(opt.stacksize, 1);  /* create state */
+  L = lua_newstate(opt.stacksize, 1);  /* create state */
   USERINIT();  /* open libraries */
   register_getargs(argv);  /* create `getargs' function */
   status = handle_argv(argv+1, &opt);
   if (opt.toclose)
-    lua_close();
+    lua_close(L);
   return status;
 }
 

+ 78 - 173
lua.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lua.h,v 1.58 2000/08/14 19:10:14 roberto Exp roberto $
+** $Id: lua.h,v 1.59 2000/08/17 13:18:01 roberto Exp roberto $
 ** Lua - An Extensible Extension Language
 ** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
 ** e-mail: [email protected]
@@ -30,8 +30,10 @@
 
 #define LUA_ANYTAG	(-1)
 
+#define LUA_MULTRET	(-1)
 
-/* error code for lua_do* */
+
+/* error codes for lua_do* */
 #define LUA_ERRFILE	2
 #define LUA_ERRSYNTAX	3
 #define LUA_ERRRUN	1
@@ -40,95 +42,103 @@
 
 typedef struct lua_State lua_State;
 
-typedef void (*lua_CFunction) (lua_State *L);
-
-typedef struct lua_TObject *lua_Object;
-
-#define LUA_NOOBJECT	((lua_Object)0)
+typedef int (*lua_CFunction) (lua_State *L);
 
 
+/*
+** state manipulation
+*/
 lua_State     *lua_newstate (int stacksize, int builtin);
 void           lua_close (lua_State *L);
 
-lua_Object     lua_settagmethod (lua_State *L, int tag, const char *event);
-                                                       /* In: new method */
-lua_Object     lua_gettagmethod (lua_State *L, int tag, const char *event);
 
-int            lua_newtag (lua_State *L);
-int            lua_copytagmethods (lua_State *L, int tagto, int tagfrom);
-void           lua_settag (lua_State *L, int tag); /* In: object */
-
-void           lua_error (lua_State *L, const char *s);
-int            lua_dofile (lua_State *L, const char *filename);
-                                                        /* Out: returns */
-int            lua_dostring (lua_State *L, const char *str);
-                                                        /* Out: returns */
-int            lua_dobuffer (lua_State *L, const char *buff, size_t size,
-                             const char *name);         /* Out: returns */
-int            lua_callfunction (lua_State *L, lua_Object f);
-					  /* In: arguments; Out: returns */
-
-void	       lua_beginblock (lua_State *L);
-void	       lua_endblock (lua_State *L);
-
-void           lua_pushglobals (lua_State *L);
-void           lua_setglobals (lua_State *L, lua_Object newtable);
+/*
+** basic stack manipulation
+*/
+int            lua_gettop (lua_State *L);
+void           lua_settop (lua_State *L, int index);
+void           lua_pushobject (lua_State *L, int index);
 
-lua_Object     lua_lua2C (lua_State *L, int number);
-#define	       lua_getparam		lua_lua2C
-#define	       lua_getresult		lua_lua2C
 
-const char    *lua_type (lua_State *L, lua_Object obj);
+/*
+** access functions (stack -> C)
+*/
 
-int            lua_isnil (lua_State *L, lua_Object obj);
-int            lua_istable (lua_State *L, lua_Object obj);
-int            lua_isuserdata (lua_State *L, lua_Object obj);
-int            lua_iscfunction (lua_State *L, lua_Object obj);
-int            lua_isnumber (lua_State *L, lua_Object obj);
-int            lua_isstring (lua_State *L, lua_Object obj);
-int            lua_isfunction (lua_State *L, lua_Object obj);
+const char    *lua_type (lua_State *L, int index);
+int            lua_isnumber (lua_State *L, int index);
+int            lua_iscfunction (lua_State *L, int index);
+int            lua_tag (lua_State *L, int index);
 
-int            lua_equal (lua_State *L, lua_Object o1, lua_Object o2);
+int            lua_equal (lua_State *L, int index1, int index2);
 
-double         lua_getnumber (lua_State *L, lua_Object obj);
-const char    *lua_getstring (lua_State *L, lua_Object obj);
-size_t         lua_strlen (lua_State *L, lua_Object obj);
-lua_CFunction  lua_getcfunction (lua_State *L, lua_Object obj);
-void	      *lua_getuserdata (lua_State *L, lua_Object obj);
+double         lua_tonumber (lua_State *L, int index);
+const char    *lua_tostring (lua_State *L, int index);
+size_t         lua_strlen (lua_State *L, int index);
+lua_CFunction  lua_tocfunction (lua_State *L, int index);
+void	      *lua_touserdata (lua_State *L, int index);
 
 
-void 	       lua_pushnil (lua_State *L);
+/*
+** push functions (C -> stack)
+*/
+void           lua_pushnil (lua_State *L);
 void           lua_pushnumber (lua_State *L, double n);
 void           lua_pushlstring (lua_State *L, const char *s, size_t len);
 void           lua_pushstring (lua_State *L, const char *s);
 void           lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
 void           lua_pushusertag (lua_State *L, void *u, int tag);
-void           lua_pushobject (lua_State *L, lua_Object obj);
 
-lua_Object     lua_pop (lua_State *L);
 
-lua_Object     lua_getglobal (lua_State *L, const char *name);
-void           lua_setglobal (lua_State *L, const char *name); /* In: value */
+/*
+** get functions (Lua -> stack)
+*/
+void           lua_getglobal (lua_State *L, const char *name);
+void           lua_gettable (lua_State *L);
+void           lua_rawget (lua_State *L);
+void           lua_getglobals (lua_State *L);
+void           lua_gettagmethod (lua_State *L, int tag, const char *event);
 
-void           lua_settable (lua_State *L); /* In: table, index, value */
-lua_Object     lua_gettable (lua_State *L); /* In: table, index */
+int            lua_getref (lua_State *L, int ref);
 
-void           lua_rawset (lua_State *L); /* In: table, index, value */
-lua_Object     lua_rawget (lua_State *L); /* In: table, index */
+void           lua_newtable (lua_State *L);
 
-int            lua_tag (lua_State *L, lua_Object obj);
 
-int            lua_next (lua_State *L, lua_Object o, int i);
-						/* Out: index, value */ 
+/*
+** set functions (stack -> Lua)
+*/
+void           lua_setglobal (lua_State *L, const char *name);
+void           lua_settable (lua_State *L);
+void           lua_rawset (lua_State *L);
+void           lua_setglobals (lua_State *L);
+void           lua_settagmethod (lua_State *L, int tag, const char *event);
+int            lua_ref (lua_State *L, int lock);
 
-int            lua_ref (lua_State *L, int lock); /* In: value */
-int            lua_pushref (lua_State *L, int ref);  /* Out: value */
-void	       lua_unref (lua_State *L, int ref);
 
-lua_Object     lua_createtable (lua_State *L);
+/*
+** "do" functions (run Lua code)
+*/
+int            lua_call (lua_State *L, int nargs, int nresults);
+int            lua_dofile (lua_State *L, const char *filename);
+int            lua_dostring (lua_State *L, const char *str);
+int            lua_dobuffer (lua_State *L, const char *buff, size_t size,
+                             const char *name);
+
+
+/*
+** miscelaneous functions
+*/
+int            lua_newtag (lua_State *L);
+int            lua_copytagmethods (lua_State *L, int tagto, int tagfrom);
+void           lua_settag (lua_State *L, int tag);
+
+void           lua_error (lua_State *L, const char *s);
+
+void	       lua_unref (lua_State *L, int ref);
 
 long	       lua_collectgarbage (lua_State *L, long limit);
 
+int            lua_next (lua_State *L, int index, int i);
+
 
 
 /* 
@@ -137,122 +147,17 @@ long	       lua_collectgarbage (lua_State *L, long limit);
 ** ===============================================================
 */
 
-#ifndef LUA_SINGLESTATE
-
-#define lua_call(L,name)	lua_callfunction(L, lua_getglobal(L, name))
-#define lua_getref(L, ref)  (lua_pushref(L, ref) ? lua_pop(L) : LUA_NOOBJECT)
-#define lua_refobject(L,o,l)	(lua_pushobject(L, o), lua_ref(L, l))
 #define lua_register(L,n,f)	(lua_pushcfunction(L, f), lua_setglobal(L, n))
 #define lua_pushuserdata(L,u)	lua_pushusertag(L, u, 0)
 #define lua_pushcfunction(L,f)	lua_pushcclosure(L, f, 0)
 #define lua_clonetag(L,t)	lua_copytagmethods(L, lua_newtag(L), (t))
 
-#else
-
-#define lua_call(name)		lua_callfunction(lua_getglobal(name))
-#define lua_getref(ref)		(lua_pushref(ref) ? lua_pop() : LUA_NOOBJECT)
-#define lua_refobject(o,l)	(lua_pushobject(o), lua_ref(l))
-#define lua_register(n,f)	(lua_pushcfunction(f), lua_setglobal(n))
-#define lua_pushuserdata(u)	lua_pushusertag(u, 0)
-#define lua_pushcfunction(f)	lua_pushcclosure(f, 0)
-#define lua_clonetag(t)		lua_copytagmethods(lua_newtag(), (t))
-
-#endif
-
-
-
-#ifdef LUA_SINGLESTATE
-/* 
-** {==============================================================
-** Macros for single-state use
-** ===============================================================
-*/
-
-extern lua_State *lua_state;
-
-#define lua_open()	((void)(lua_state?0:(lua_state=lua_newstate(0, 1))))
-
-#define lua_close()		(lua_close)(lua_state)
-#define lua_settagmethod(tag,event)	(lua_settagmethod)(lua_state, tag,event)
-#define lua_gettagmethod(tag,event)	(lua_gettagmethod)(lua_state, tag,event)
-#define lua_newtag()		(lua_newtag)(lua_state)
-#define lua_copytagmethods(tagto,tagfrom)	\
-		(lua_copytagmethods)(lua_state, tagto,tagfrom)
-#define lua_settag(tag)		(lua_settag)(lua_state, tag)
-#define lua_error(s)		(lua_error)(lua_state, s)
-#define lua_dofile(filename)	(lua_dofile)(lua_state, filename)
-#define lua_dostring(str)	(lua_dostring)(lua_state, str)
-#define lua_dobuffer(b,s,n)	(lua_dobuffer)(lua_state, b,s,n)
-#define lua_callfunction(f)	(lua_callfunction)(lua_state, f)
-#define lua_beginblock()	(lua_beginblock)(lua_state)
-#define lua_endblock()		(lua_endblock)(lua_state)
-#define lua_pushglobals()	(lua_pushglobals)(lua_state)
-#define lua_setglobals(t)	(lua_setglobals)(lua_state, t)
-#define lua_lua2C(number)	(lua_lua2C)(lua_state, number)
-#define lua_type(obj)		(lua_type)(lua_state, obj)
-#define lua_isnil(obj)		(lua_isnil)(lua_state, obj)
-#define lua_istable(obj)	(lua_istable)(lua_state, obj)
-#define lua_isuserdata(obj)	(lua_isuserdata)(lua_state, obj)
-#define lua_iscfunction(obj)	(lua_iscfunction)(lua_state, obj)
-#define lua_isnumber(obj)	(lua_isnumber)(lua_state, obj)
-#define lua_isstring(obj)	(lua_isstring)(lua_state, obj)
-#define lua_isfunction(obj)	(lua_isfunction)(lua_state, obj)
-#define lua_equal(o1,o2)	(lua_equal)(lua_state, o1,o2)
-#define lua_getnumber(obj)	(lua_getnumber)(lua_state, obj)
-#define lua_getstring(obj)	(lua_getstring)(lua_state, obj)
-#define lua_strlen(obj)		(lua_strlen)(lua_state, obj)
-#define lua_getcfunction(obj)	(lua_getcfunction)(lua_state, obj)
-#define lua_getuserdata(obj)	(lua_getuserdata)(lua_state, obj)
-#define lua_pushnil()		(lua_pushnil)(lua_state)
-#define lua_pushnumber(n)	(lua_pushnumber)(lua_state, n)
-#define lua_pushlstring(s,len)	(lua_pushlstring)(lua_state, s,len)
-#define lua_pushstring(s)	(lua_pushstring)(lua_state, s)
-#define lua_pushusertag(u,tag)	(lua_pushusertag)(lua_state, u,tag)
-#define lua_pushobject(obj)	(lua_pushobject)(lua_state, obj)
-#define lua_pop()		(lua_pop)(lua_state)
-#define lua_getglobal(name)	(lua_getglobal)(lua_state, name)
-#define lua_setglobal(name)	(lua_setglobal)(lua_state, name)
-#define lua_settable()		(lua_settable)(lua_state)
-#define lua_gettable()		(lua_gettable)(lua_state)
-#define lua_rawset()		(lua_rawset)(lua_state)
-#define lua_rawget()		(lua_rawget)(lua_state)
-#define lua_tag(obj)		(lua_tag)(lua_state, obj)
-#define lua_next(o,i)		(lua_next)(lua_state, o,i)
-#define lua_ref(lock)		(lua_ref)(lua_state, lock)
-#define lua_pushref(ref)	(lua_pushref)(lua_state, ref)
-#define lua_unref(ref)		(lua_unref)(lua_state, ref)
-#define lua_createtable()	(lua_createtable)(lua_state)
-#define lua_collectgarbage(limit)	(lua_collectgarbage)(lua_state, limit)
-/*
-** the following typecast is a little dirty, but we know of no other
-** way to keep compatibility with old definition of `lua_CFunction'
-*/
-#define lua_pushcclosure(fn,n) \
-		(lua_pushcclosure)(lua_state, (lua_CFunction)(fn), n)
-
-
-/*
-** }==============================================================
-*/
-#endif
-
-/*
-** compatibility with 3.2
-** these functions are only available when Lua is compiled with 
-** the option LUA_DEPRECATETFUNCS
-*/
-
-#define lua_rawsettable		lua_rawset
-#define lua_rawgettable		lua_rawget
-
-lua_Object     lua_rawgetglobal (lua_State *L, const char *name);
-void           lua_rawsetglobal (lua_State *L, const char *name);/* In: value */
-
-#ifdef LUA_SINGLESTATE
-#define lua_rawgetglobal(name)	(lua_rawgetglobal(lua_state, name))
-#define lua_rawsetglobal(name)	(lua_rawsetglobal(lua_state, name))
-#endif
-
+#define lua_isfunction(L,n)	(*lua_type(L,n) == 'f')
+#define lua_isstring(L,n)	(lua_tostring(L,n))
+#define lua_istable(L,n)	(*lua_type(L,n) == 't')
+#define lua_isuserdata(L,n)	(*lua_type(L,n) == 'u')
+#define lua_isnil(L,n)		(lua_type(L,n)[2] == 'l')
+#define lua_isnull(L,n)		(*lua_type(L,n) == 'N')
 
 #endif
 

+ 4 - 12
luadebug.h

@@ -1,5 +1,5 @@
 /*
-** $Id: luadebug.h,v 1.11 2000/08/08 20:42:07 roberto Exp roberto $
+** $Id: luadebug.h,v 1.12 2000/08/11 16:17:28 roberto Exp roberto $
 ** Debugging API
 ** See Copyright Notice in lua.h
 */
@@ -19,8 +19,8 @@ typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
 
 int lua_getstack (lua_State *L, int level, lua_Debug *ar);
 int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
-int lua_getlocal (lua_State *L, const lua_Debug *ar, lua_Localvar *v);
-int lua_setlocal (lua_State *L, const lua_Debug *ar, lua_Localvar *v);
+const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int localnum);
+const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int localnum);
 
 lua_Hook lua_setcallhook (lua_State *L, lua_Hook func);
 lua_Hook lua_setlinehook (lua_State *L, lua_Hook func);
@@ -36,16 +36,8 @@ struct lua_Debug {
   const char *name;      /* (n) */
   const char *namewhat;  /* (n) `global', `tag method', `local', `field' */
   int nups;              /* (u) number of upvalues */
-  lua_Object func;       /* (f) function being executed */
   /* private part */
-  lua_Object _func;  /* active function */
-};
-
-
-struct lua_Localvar {
-  int index;
-  const char *name;
-  lua_Object value;
+  struct lua_TObject *_func;  /* active function */
 };
 
 

+ 2 - 2
lundump.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lundump.c,v 1.24 2000/08/09 19:16:57 roberto Exp roberto $
+** $Id: lundump.c,v 1.25 2000/08/24 14:19:39 roberto Exp roberto $
 ** load bytecodes from files
 ** See Copyright Notice in lua.h
 */
@@ -130,7 +130,7 @@ static void LoadCode (lua_State* L, Proto* tf, ZIO* Z)
 }
 
 static void LoadLocals (lua_State* L, Proto* tf, ZIO* Z)
-{
+{ 
 }
 
 static Proto* LoadFunction (lua_State* L, ZIO* Z, int native);