Jelajahi Sumber

macros LUA_ENTRY/LUA_EXIT to control exclusive access to Lua core

Roberto Ierusalimschy 24 tahun lalu
induk
melakukan
71ae4801d6
11 mengubah file dengan 420 tambahan dan 149 penghapusan
  1. 249 72
      lapi.c
  2. 51 22
      ldebug.c
  3. 23 9
      ldo.c
  4. 2 1
      ldo.h
  5. 3 3
      lmem.c
  6. 3 2
      lobject.c
  7. 38 22
      lstate.c
  8. 21 1
      lstate.h
  9. 5 4
      ltable.c
  10. 15 4
      ltm.c
  11. 10 9
      lvm.c

+ 249 - 72
lapi.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 1.117 2001/01/18 15:59:09 roberto Exp roberto $
+** $Id: lapi.c,v 1.118 2001/01/19 13:20:30 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -54,7 +54,11 @@ void luaA_pushobject (lua_State *L, const TObject *o) {
 }
 
 LUA_API int lua_stackspace (lua_State *L) {
-  return (L->stack_last - L->top);
+  int i;
+  LUA_ENTRY;
+  i = (L->stack_last - L->top);
+  LUA_EXIT;
+  return i;
 }
 
 
@@ -65,36 +69,50 @@ LUA_API int lua_stackspace (lua_State *L) {
 
 
 LUA_API int lua_gettop (lua_State *L) {
-  return (L->top - L->Cbase);
+  int i;
+  LUA_ENTRY;
+  i = (L->top - L->Cbase);
+  LUA_EXIT;
+  return i;
 }
 
 
 LUA_API void lua_settop (lua_State *L, int index) {
+  LUA_ENTRY;
   if (index >= 0)
     luaD_adjusttop(L, L->Cbase, index);
   else
     L->top = L->top+index+1;  /* index is negative */
+  LUA_EXIT;
 }
 
 
 LUA_API void lua_remove (lua_State *L, int index) {
-  StkId p = luaA_index(L, index);
+  StkId p;
+  LUA_ENTRY;
+  p = luaA_index(L, index);
   while (++p < L->top) setobj(p-1, p);
   L->top--;
+  LUA_EXIT;
 }
 
 
 LUA_API void lua_insert (lua_State *L, int index) {
-  StkId p = luaA_index(L, index);
+  StkId p;
   StkId q;
+  LUA_ENTRY;
+  p = luaA_index(L, index);
   for (q = L->top; q>p; q--) setobj(q, q-1);
   setobj(p, L->top);
+  LUA_EXIT;
 }
 
 
 LUA_API void lua_pushvalue (lua_State *L, int index) {
+  LUA_ENTRY;
   setobj(L->top, luaA_index(L, index));
   api_incr_top(L);
+  LUA_EXIT;
 }
 
 
@@ -105,24 +123,43 @@ LUA_API void lua_pushvalue (lua_State *L, int index) {
 
 
 LUA_API int lua_type (lua_State *L, int index) {
-  StkId o = luaA_indexAcceptable(L, index);
-  return (o == NULL) ? LUA_TNONE : ttype(o);
+  StkId o;
+  int i;
+  LUA_ENTRY;
+  o = luaA_indexAcceptable(L, index);
+  i = (o == NULL) ? LUA_TNONE : ttype(o);
+  LUA_EXIT;
+  return i;
 }
 
 LUA_API const char *lua_typename (lua_State *L, int t) {
+  const char *s;
+  LUA_ENTRY;
   UNUSED(L);
-  return (t == LUA_TNONE) ? "no value" : luaO_typenames[t];
+  s = (t == LUA_TNONE) ? "no value" : luaO_typenames[t];
+  LUA_EXIT;
+  return s;
 }
 
 
 LUA_API int lua_iscfunction (lua_State *L, int index) {
-  StkId o = luaA_indexAcceptable(L, index);
-  return (o == NULL) ? 0 : iscfunction(o);
+  StkId o;
+  int i;
+  LUA_ENTRY;
+  o = luaA_indexAcceptable(L, index);
+  i = (o == NULL) ? 0 : iscfunction(o);
+  LUA_EXIT;
+  return i;
 }
 
 LUA_API int lua_isnumber (lua_State *L, int index) {
-  TObject *o = luaA_indexAcceptable(L, index);
-  return (o == NULL) ? 0 : (tonumber(o) == 0);
+  TObject *o;
+  int i;
+  LUA_ENTRY;
+  o = luaA_indexAcceptable(L, index);
+  i = (o == NULL) ? 0 : (tonumber(o) == 0);
+  LUA_EXIT;
+  return i;
 }
 
 LUA_API int lua_isstring (lua_State *L, int index) {
@@ -132,62 +169,113 @@ LUA_API int lua_isstring (lua_State *L, int index) {
 
 
 LUA_API int lua_tag (lua_State *L, int index) {
-  StkId o = luaA_indexAcceptable(L, index);
-  return (o == NULL) ? LUA_NOTAG : luaT_tag(o);
+  StkId o;
+  int i;
+  LUA_ENTRY;
+  o = luaA_indexAcceptable(L, index);
+  i = (o == NULL) ? LUA_NOTAG : luaT_tag(o);
+  LUA_EXIT;
+  return i;
 }
 
 LUA_API int lua_equal (lua_State *L, int index1, int index2) {
-  StkId o1 = luaA_indexAcceptable(L, index1);
-  StkId o2 = luaA_indexAcceptable(L, index2);
-  if (o1 == NULL || o2 == NULL) return 0;  /* index out-of-range */
-  else return luaO_equalObj(o1, o2);
+  StkId o1, o2;
+  int i;
+  LUA_ENTRY;
+  o1 = luaA_indexAcceptable(L, index1);
+  o2 = luaA_indexAcceptable(L, index2);
+  i = (o1 == NULL || o2 == NULL) ? 0  /* index out-of-range */
+                                 : luaO_equalObj(o1, o2);
+  LUA_EXIT;
+  return i;
 }
 
 LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
-  StkId o1 = luaA_indexAcceptable(L, index1);
-  StkId o2 = luaA_indexAcceptable(L, index2);
-  if (o1 == NULL || o2 == NULL) return 0;  /* index out-of-range */
-  else return luaV_lessthan(L, o1, o2, L->top);
+  StkId o1, o2;
+  int i;
+  LUA_ENTRY;
+  o1 = luaA_indexAcceptable(L, index1);
+  o2 = luaA_indexAcceptable(L, index2);
+  i = (o1 == NULL || o2 == NULL) ? 0  /* index out-of-range */
+                                 : luaV_lessthan(L, o1, o2, L->top);
+  LUA_EXIT;
+  return i;
 }
 
 
 
 LUA_API lua_Number lua_tonumber (lua_State *L, int index) {
-  StkId o = luaA_indexAcceptable(L, index);
-  return (o == NULL || tonumber(o)) ? 0 : nvalue(o);
+  StkId o;
+  lua_Number n;
+  LUA_ENTRY;
+  o = luaA_indexAcceptable(L, index);
+  n = (o == NULL || tonumber(o)) ? 0 : nvalue(o);
+  LUA_EXIT;
+  return n;
 }
 
 LUA_API const char *lua_tostring (lua_State *L, int index) {
-  StkId o = luaA_indexAcceptable(L, index);
-  return (o == NULL || tostring(L, o)) ? NULL : svalue(o);
+  StkId o;
+  const char *s;
+  LUA_ENTRY;
+  o = luaA_indexAcceptable(L, index);
+  s = (o == NULL || tostring(L, o)) ? NULL : svalue(o);
+  LUA_EXIT;
+  return s;
 }
 
 LUA_API size_t lua_strlen (lua_State *L, int index) {
-  StkId o = luaA_indexAcceptable(L, index);
-  return (o == NULL || tostring(L, o)) ? 0 : tsvalue(o)->len;
+  StkId o;
+  size_t l;
+  LUA_ENTRY;
+  o = luaA_indexAcceptable(L, index);
+  l = (o == NULL || tostring(L, o)) ? 0 : tsvalue(o)->len;
+  LUA_EXIT;
+  return l;
 }
 
 LUA_API lua_CFunction lua_tocfunction (lua_State *L, int index) {
-  StkId o = luaA_indexAcceptable(L, index);
-  return (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->f.c;
+  StkId o;
+  lua_CFunction f;
+  LUA_ENTRY;
+  o = luaA_indexAcceptable(L, index);
+  f = (o == NULL || !iscfunction(o)) ? NULL : clvalue(o)->f.c;
+  LUA_EXIT;
+  return f;
 }
 
 LUA_API void *lua_touserdata (lua_State *L, int index) {
-  StkId o = luaA_indexAcceptable(L, index);
-  return (o == NULL || ttype(o) != LUA_TUSERDATA) ? NULL :
+  StkId o;
+  void *p;
+  LUA_ENTRY;
+  o = luaA_indexAcceptable(L, index);
+  p = (o == NULL || ttype(o) != LUA_TUSERDATA) ? NULL :
                                                     tsvalue(o)->u.d.value;
+  LUA_EXIT;
+  return p;
 }
 
 LUA_API const void *lua_topointer (lua_State *L, int index) {
-  StkId o = luaA_indexAcceptable(L, index);
-  if (o == NULL) return NULL;
-  switch (ttype(o)) {
-    case LUA_TTABLE: 
-      return hvalue(o);
-    case LUA_TFUNCTION:
-      return clvalue(o);
-    default: return NULL;
+  StkId o;
+  const void *p;
+  LUA_ENTRY;
+  o = luaA_indexAcceptable(L, index);
+  if (o == NULL) p = NULL;
+  else {
+    switch (ttype(o)) {
+      case LUA_TTABLE: 
+        p = hvalue(o);
+        break;
+      case LUA_TFUNCTION:
+        p = clvalue(o);
+        break;
+      default:
+        p = NULL;
+        break;
+    }
   }
+  LUA_EXIT;
+  return p;
 }
 
 
@@ -198,20 +286,26 @@ LUA_API const void *lua_topointer (lua_State *L, int index) {
 
 
 LUA_API void lua_pushnil (lua_State *L) {
+  LUA_ENTRY;
   setnilvalue(L->top);
   api_incr_top(L);
+  LUA_EXIT;
 }
 
 
 LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
+  LUA_ENTRY;
   setnvalue(L->top, n);
   api_incr_top(L);
+  LUA_EXIT;
 }
 
 
 LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
+  LUA_ENTRY;
   setsvalue(L->top, luaS_newlstr(L, s, len));
   api_incr_top(L);
+  LUA_EXIT;
 }
 
 
@@ -224,16 +318,20 @@ LUA_API void lua_pushstring (lua_State *L, const char *s) {
 
 
 LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
+  LUA_ENTRY;
   luaV_Cclosure(L, fn, n);
+  LUA_EXIT;
 }
 
 
 LUA_API void lua_pushusertag (lua_State *L, void *u, int tag) {
+  LUA_ENTRY;
   /* ORDER LUA_T */
   if (!(tag == LUA_ANYTAG || tag == LUA_TUSERDATA || validtag(G(L), tag)))
     luaO_verror(L, "invalid tag for a userdata (%d)", tag);
   setuvalue(L->top, luaS_createudata(L, u, tag));
   api_incr_top(L);
+  LUA_EXIT;
 }
 
 
@@ -244,60 +342,80 @@ LUA_API void lua_pushusertag (lua_State *L, void *u, int tag) {
 
 
 LUA_API void lua_getglobal (lua_State *L, const char *name) {
-  StkId top = L->top;
+  StkId top;
+  LUA_ENTRY;
+  top = L->top;
   setobj(top, luaV_getglobal(L, luaS_new(L, name)));
   L->top = top;
   api_incr_top(L);
+  LUA_EXIT;
 }
 
 
 LUA_API void lua_gettable (lua_State *L, int index) {
-  StkId t = Index(L, index);
-  StkId top = L->top;
+  StkId t, top;
+  LUA_ENTRY;
+  t = Index(L, index);
+  top = L->top;
   setobj(top-1, luaV_gettable(L, t));
   L->top = top;  /* tag method may change top */
+  LUA_EXIT;
 }
 
 
 LUA_API void lua_rawget (lua_State *L, int index) {
-  StkId t = Index(L, index);
+  StkId t;
+  LUA_ENTRY;
+  t = Index(L, index);
   lua_assert(ttype(t) == LUA_TTABLE);
   setobj(L->top - 1, luaH_get(hvalue(t), L->top - 1));
+  LUA_EXIT;
 }
 
 
 LUA_API void lua_rawgeti (lua_State *L, int index, int n) {
-  StkId o = Index(L, index);
+  StkId o;
+  LUA_ENTRY;
+  o = Index(L, index);
   lua_assert(ttype(o) == LUA_TTABLE);
   setobj(L->top, luaH_getnum(hvalue(o), n));
   api_incr_top(L);
+  LUA_EXIT;
 }
 
 
 LUA_API void lua_getglobals (lua_State *L) {
+  LUA_ENTRY;
   sethvalue(L->top, L->gt);
   api_incr_top(L);
+  LUA_EXIT;
 }
 
 
 LUA_API int lua_getref (lua_State *L, int ref) {
+  int status = 1;
+  LUA_ENTRY;
   if (ref == LUA_REFNIL) {
     setnilvalue(L->top);
+    api_incr_top(L);
   }
   else if (0 <= ref && ref < G(L)->nref &&
           (G(L)->refArray[ref].st == LOCK || G(L)->refArray[ref].st == HOLD)) {
     setobj(L->top, &G(L)->refArray[ref].o);
+    api_incr_top(L);
   }
   else
-    return 0;
-  api_incr_top(L);
-  return 1;
+    status = 0;
+  LUA_EXIT;
+  return status;
 }
 
 
 LUA_API void lua_newtable (lua_State *L) {
+  LUA_ENTRY;
   sethvalue(L->top, luaH_new(L, 0));
   api_incr_top(L);
+  LUA_EXIT;
 }
 
 
@@ -308,45 +426,61 @@ LUA_API void lua_newtable (lua_State *L) {
 
 
 LUA_API void lua_setglobal (lua_State *L, const char *name) {
-  StkId top = L->top;
+  StkId top;
+  LUA_ENTRY;
+  top = L->top;
   luaV_setglobal(L, luaS_new(L, name));
   L->top = top-1;  /* remove element from the top */
+  LUA_EXIT;
 }
 
 
 LUA_API void lua_settable (lua_State *L, int index) {
-  StkId t = Index(L, index);
-  StkId top = L->top;
+  StkId t, top;
+  LUA_ENTRY;
+  t = Index(L, index);
+  top = L->top;
   luaV_settable(L, t, top-2);
   L->top = top-2;  /* pop index and value */
+  LUA_EXIT;
 }
 
 
 LUA_API void lua_rawset (lua_State *L, int index) {
-  StkId t = Index(L, index);
+  StkId t;
+  LUA_ENTRY;
+  t = Index(L, index);
   lua_assert(ttype(t) == LUA_TTABLE);
   setobj(luaH_set(L, hvalue(t), L->top-2), (L->top-1));
   L->top -= 2;
+  LUA_EXIT;
 }
 
 
 LUA_API void lua_rawseti (lua_State *L, int index, int n) {
-  StkId o = Index(L, index);
+  StkId o;
+  LUA_ENTRY;
+  o = Index(L, index);
   lua_assert(ttype(o) == LUA_TTABLE);
   setobj(luaH_setnum(L, hvalue(o), n), (L->top-1));
   L->top--;
+  LUA_EXIT;
 }
 
 
 LUA_API void lua_setglobals (lua_State *L) {
-  StkId newtable = --L->top;
+  StkId newtable;
+  LUA_ENTRY;
+  newtable = --L->top;
   lua_assert(ttype(newtable) == LUA_TTABLE);
   L->gt = hvalue(newtable);
+  LUA_EXIT;
 }
 
 
 LUA_API int lua_ref (lua_State *L,  int lock) {
   int ref;
+  LUA_ENTRY;
   if (ttype(L->top-1) == LUA_TNIL)
     ref = LUA_REFNIL;
   else {
@@ -363,6 +497,7 @@ LUA_API int lua_ref (lua_State *L,  int lock) {
     G(L)->refArray[ref].st = lock ? LOCK : HOLD;
   }
   L->top--;
+  LUA_EXIT;
   return ref;
 }
 
@@ -373,7 +508,9 @@ LUA_API int lua_ref (lua_State *L,  int lock) {
 */
 
 LUA_API void lua_rawcall (lua_State *L, int nargs, int nresults) {
+  LUA_ENTRY;
   luaD_call(L, L->top-(nargs+1), nresults);
+  LUA_EXIT;
 }
 
 
@@ -386,19 +523,29 @@ LUA_API void lua_rawcall (lua_State *L, int nargs, int nresults) {
 #define GCunscale(x)		((mem_int)(x)<<10)
 
 LUA_API int lua_getgcthreshold (lua_State *L) {
-  return GCscale(G(L)->GCthreshold);
+  int threshold;
+  LUA_ENTRY;
+  threshold = GCscale(G(L)->GCthreshold);
+  LUA_EXIT;
+  return threshold;
 }
 
 LUA_API int lua_getgccount (lua_State *L) {
-  return GCscale(G(L)->nblocks);
+  int count;
+  LUA_ENTRY;
+  count = GCscale(G(L)->nblocks);
+  LUA_EXIT;
+  return count;
 }
 
 LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) {
+  LUA_ENTRY;
   if (newthreshold > GCscale(ULONG_MAX))
     G(L)->GCthreshold = ULONG_MAX;
   else
     G(L)->GCthreshold = GCunscale(newthreshold);
   luaC_checkGC(L);
+  LUA_EXIT;
 }
 
 
@@ -407,6 +554,7 @@ LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) {
 */
 
 LUA_API void lua_settag (lua_State *L, int tag) {
+  LUA_ENTRY;
   luaT_realtag(L, tag);
   switch (ttype(L->top-1)) {
     case LUA_TTABLE:
@@ -419,69 +567,98 @@ LUA_API void lua_settag (lua_State *L, int tag) {
       luaO_verror(L, "cannot change the tag of a %.20s",
                   luaO_typename(L->top-1));
   }
+  LUA_EXIT;
+}
+
+
+LUA_API void lua_error (lua_State *L, const char *s) {
+  LUA_ENTRY;
+  luaD_error(L, s);
+  LUA_EXIT;
 }
 
 
 LUA_API void lua_unref (lua_State *L, int ref) {
+  LUA_ENTRY;
   if (ref >= 0) {
     lua_assert(ref < G(L)->nref && G(L)->refArray[ref].st < 0);
     G(L)->refArray[ref].st = G(L)->refFree;
     G(L)->refFree = ref;
   }
+  LUA_EXIT;
 }
 
 
 LUA_API int lua_next (lua_State *L, int index) {
-  StkId t = luaA_index(L, index);
+  StkId t;
   Node *n;
+  int more;
+  LUA_ENTRY;
+  t = luaA_index(L, index);
   lua_assert(ttype(t) == LUA_TTABLE);
   n = luaH_next(L, hvalue(t), luaA_index(L, -1));
   if (n) {
     setobj(L->top-1, key(n));
     setobj(L->top, val(n));
     api_incr_top(L);
-    return 1;
+    more = 1;
   }
   else {  /* no more elements */
     L->top -= 1;  /* remove key */
-    return 0;
+    more = 0;
   }
+  LUA_EXIT;
+  return more;
 }
 
 
 LUA_API int lua_getn (lua_State *L, int index) {
-  Hash *h = hvalue(luaA_index(L, index));
-  const TObject *value = luaH_getstr(h, luaS_newliteral(L, "n"));  /* = h.n */
+  Hash *h;
+  const TObject *value;
+  int n;
+  LUA_ENTRY;
+  h = hvalue(luaA_index(L, index));
+  value = luaH_getstr(h, luaS_newliteral(L, "n"));  /* = h.n */
   if (ttype(value) == LUA_TNUMBER)
-    return (int)nvalue(value);
+    n = (int)nvalue(value);
   else {
     lua_Number max = 0;
     int i = h->size;
-    Node *n = h->node;
+    Node *nd = h->node;
     while (i--) {
-      if (ttype(key(n)) == LUA_TNUMBER &&
-          ttype(val(n)) != LUA_TNIL &&
-          nvalue(key(n)) > max)
-        max = nvalue(key(n));
-      n++;
+      if (ttype(key(nd)) == LUA_TNUMBER &&
+          ttype(val(nd)) != LUA_TNIL &&
+          nvalue(key(nd)) > max)
+        max = nvalue(key(nd));
+      nd++;
     }
-    return (int)max;
+    n = (int)max;
   }
+  LUA_EXIT;
+  return n;
 }
 
 
 LUA_API void lua_concat (lua_State *L, int n) {
-  StkId top = L->top;
+  StkId top;
+  LUA_ENTRY;
+  top = L->top;
   luaV_strconc(L, n, top);
   L->top = top-(n-1);
   luaC_checkGC(L);
+  LUA_EXIT;
 }
 
 
 LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
-  TString *ts = luaS_newudata(L, size, NULL);
+  TString *ts;
+  void *p;
+  LUA_ENTRY;
+  ts = luaS_newudata(L, size, NULL);
   setuvalue(L->top, ts);
   api_incr_top(L);
-  return ts->u.d.value;
+  p = ts->u.d.value;
+  LUA_EXIT;
+  return p;
 }
 

+ 51 - 22
ldebug.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldebug.c,v 1.53 2001/01/18 15:59:09 roberto Exp roberto $
+** $Id: ldebug.c,v 1.54 2001/01/19 13:20:30 roberto Exp roberto $
 ** Debug Interface
 ** See Copyright Notice in lua.h
 */
@@ -41,15 +41,21 @@ static int isLmark (StkId o) {
 
 
 LUA_API lua_Hook lua_setcallhook (lua_State *L, lua_Hook func) {
-  lua_Hook oldhook = L->callhook;
+  lua_Hook oldhook;
+  LUA_ENTRY;
+  oldhook = L->callhook;
   L->callhook = func;
+  LUA_EXIT;
   return oldhook;
 }
 
 
 LUA_API lua_Hook lua_setlinehook (lua_State *L, lua_Hook func) {
-  lua_Hook oldhook = L->linehook;
+  lua_Hook oldhook;
+  LUA_ENTRY;
+  oldhook = L->linehook;
   L->linehook = func;
+  LUA_EXIT;
   return oldhook;
 }
 
@@ -68,12 +74,17 @@ static StkId aux_stackedfunction (lua_State *L, int level, StkId top) {
 
 
 LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
-  StkId f = aux_stackedfunction(L, level, L->top);
-  if (f == NULL) return 0;  /* there is no such level */
+  StkId f;
+  int status;
+  LUA_ENTRY;
+  f = aux_stackedfunction(L, level, L->top);
+  if (f == NULL) status = 0;  /* there is no such level */
   else {
     ar->_func = f;
-    return 1;
+    status = 1;
   }
+  LUA_EXIT;
+  return status;
 }
 
 
@@ -149,25 +160,39 @@ static Proto *getluaproto (StkId f) {
 
 LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
   const char *name;
-  StkId f = ar->_func;
-  Proto *fp = getluaproto(f);
-  if (!fp) return NULL;  /* `f' is not a Lua function? */
-  name = luaF_getlocalname(fp, n, currentpc(f));
-  if (!name) return NULL;
-  luaA_pushobject(L, (f+1)+(n-1));  /* push value */
+  StkId f;
+  Proto *fp;
+  LUA_ENTRY;
+  name = NULL;
+  f = ar->_func;
+  fp = getluaproto(f);
+  if (fp) {  /* `f' is a Lua function? */
+    name = luaF_getlocalname(fp, n, currentpc(f));
+    if (name)
+      luaA_pushobject(L, (f+1)+(n-1));  /* push value */
+  }
+  LUA_EXIT;
   return name;
 }
 
 
 LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
   const char *name;
-  StkId f = ar->_func;
-  Proto *fp = getluaproto(f);
+  StkId f;
+  Proto *fp;
+  LUA_ENTRY;
+  name = NULL;
+  f = ar->_func;
+  fp = getluaproto(f);
   L->top--;  /* pop new value */
-  if (!fp) return NULL;  /* `f' is not a Lua function? */
-  name = luaF_getlocalname(fp, n, currentpc(f));
-  if (!name || name[0] == '(') return NULL;  /* `(' starts private locals */
-  setobj((f+1)+(n-1), L->top);
+  if (fp) {  /* `f' is a Lua function? */
+    name = luaF_getlocalname(fp, n, currentpc(f));
+    if (!name || name[0] == '(')  /* `(' starts private locals */
+      name = NULL;
+    else
+      setobj((f+1)+(n-1), L->top);
+  }
+  LUA_EXIT;
   return name;
 }
 
@@ -189,7 +214,7 @@ static void funcinfo (lua_State *L, lua_Debug *ar, StkId func) {
       cl = infovalue(func)->func;
       break;
     default:
-      lua_error(L, "value for `lua_getinfo' is not a function");
+      luaD_error(L, "value for `lua_getinfo' is not a function");
   }
   if (cl->isC) {
     ar->source = "=C";
@@ -245,7 +270,10 @@ static void getname (lua_State *L, StkId f, lua_Debug *ar) {
 
 LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
   StkId func;
-  int isactive = (*what != '>');
+  int isactive;
+  int status = 1;
+  LUA_ENTRY;
+  isactive = (*what != '>');
   if (isactive)
     func = ar->_func;
   else {
@@ -277,11 +305,12 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
         incr_top;  /* push function */
         break;
       }
-      default: return 0;  /* invalid option */
+      default: status = 0;  /* invalid option */
     }
   }
   if (!isactive) L->top--;  /* pop function */
-  return 1;
+  LUA_EXIT;
+  return status;
 }
 
 

+ 23 - 9
ldo.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.c,v 1.114 2001/01/18 15:59:09 roberto Exp roberto $
+** $Id: ldo.c,v 1.115 2001/01/19 13:20:30 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -56,7 +56,7 @@ void luaD_checkstack (lua_State *L, int n) {
     else {
       L->stack_last += EXTRA_STACK;  /* to be used by error message */
       lua_assert(L->stack_last == L->stack+L->stacksize-1);
-      lua_error(L, "stack overflow");
+      luaD_error(L, "stack overflow");
     }
   }
 }
@@ -94,7 +94,9 @@ static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) {
   StkId old_top = L->Cbase = L->top;
   luaD_checkstack(L, LUA_MINSTACK);  /* ensure minimum stack size */
   L->allowhooks = 0;  /* cannot call hooks inside a hook */
+  LUA_EXIT;
   (*hook)(L, ar);
+  LUA_ENTRY;
   lua_assert(L->allowhooks == 0);
   L->allowhooks = 1;
   L->top = old_top;
@@ -133,7 +135,9 @@ static StkId callCclosure (lua_State *L, const struct Closure *cl, StkId base) {
   luaD_checkstack(L, nup+LUA_MINSTACK);  /* ensure minimum stack size */
   for (n=0; n<nup; n++)  /* copy upvalues as extra arguments */
     setobj(L->top++, &cl->upvalue[n]);
+  LUA_EXIT;
   n = (*cl->f.c)(L);  /* do the actual call */
+  LUA_ENTRY;
   L->Cbase = old_Cbase;  /* restore old C base */
   return L->top - n;  /* return index of first result */
 }
@@ -212,13 +216,16 @@ static void f_call (lua_State *L, void *ud) {
 
 
 LUA_API int lua_call (lua_State *L, int nargs, int nresults) {
-  StkId func = L->top - (nargs+1);  /* function to be called */
+  StkId func;
   struct CallS c;
   int status;
+  LUA_ENTRY;
+  func = L->top - (nargs+1);  /* function to be called */
   c.func = func; c.nresults = nresults;
   status = luaD_runprotected(L, f_call, &c);
   if (status != 0)  /* an error occurred? */
     L->top = func;  /* remove parameters from the stack */
+  LUA_EXIT;
   return status;
 }
 
@@ -242,6 +249,7 @@ static int protectedparser (lua_State *L, ZIO *z, int bin) {
   struct ParserS p;
   mem_int old_blocks;
   int status;
+  LUA_ENTRY;
   p.z = z; p.bin = bin;
   luaC_checkGC(L);
   old_blocks = G(L)->nblocks;
@@ -253,6 +261,7 @@ static int protectedparser (lua_State *L, ZIO *z, int bin) {
   }
   else if (status == LUA_ERRRUN)  /* an error occurred: correct error code */
     status = LUA_ERRSYNTAX;
+  LUA_EXIT;
   return status;
 }
 
@@ -275,9 +284,9 @@ static int parse_file (lua_State *L, const char *filename) {
   lua_pushstring(L, (filename == NULL) ? "(stdin)" : filename);
   lua_concat(L, 2);
   filename = lua_tostring(L, -1);  /* filename = '@'..filename */
-  lua_pop(L, 1);  /* OK: there is no GC during parser */
   luaZ_Fopen(&z, f, filename);
   status = protectedparser(L, &z, bin);
+  lua_remove(L, -2);  /* remove filename */
   if (f != stdin)
     fclose(f);
   return status;
@@ -285,7 +294,8 @@ static int parse_file (lua_State *L, const char *filename) {
 
 
 LUA_API int lua_dofile (lua_State *L, const char *filename) {
-  int status = parse_file(L, filename);
+  int status;
+  status = parse_file(L, filename);
   if (status == 0)  /* parse OK? */
     status = lua_call(L, 0, LUA_MULTRET);  /* call main */
   return status;
@@ -295,14 +305,17 @@ LUA_API int lua_dofile (lua_State *L, const char *filename) {
 static int parse_buffer (lua_State *L, const char *buff, size_t size,
                          const char *name) {
   ZIO z;
+  int status;
   if (!name) name = "?";
   luaZ_mopen(&z, buff, size, name);
-  return protectedparser(L, &z, buff[0]==ID_CHUNK);
+  status = protectedparser(L, &z, buff[0]==ID_CHUNK);
+  return status;
 }
 
 
 LUA_API int lua_dobuffer (lua_State *L, const char *buff, size_t size, const char *name) {
-  int status = parse_buffer(L, buff, size, name);
+  int status;
+  status = parse_buffer(L, buff, size, name);
   if (status == 0)  /* parse OK? */
     status = lua_call(L, 0, LUA_MULTRET);  /* call main */
   return status;
@@ -333,7 +346,8 @@ static void message (lua_State *L, const char *s) {
   if (ttype(em) == LUA_TFUNCTION) {
     setobj(L->top, em);
     incr_top;
-    lua_pushstring(L, s);
+    setsvalue(L->top, luaS_new(L, s));
+    incr_top;
     luaD_call(L, L->top-2, 0);
   }
 }
@@ -342,7 +356,7 @@ static void message (lua_State *L, const char *s) {
 /*
 ** Reports an error, and jumps up to the available recovery label
 */
-LUA_API void lua_error (lua_State *L, const char *s) {
+void luaD_error (lua_State *L, const char *s) {
   if (s) message(L, s);
   luaD_breakrun(L, LUA_ERRRUN);
 }

+ 2 - 1
ldo.h

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.h,v 1.27 2000/10/05 13:00:17 roberto Exp roberto $
+** $Id: ldo.h,v 1.28 2000/10/06 12:45:25 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -26,6 +26,7 @@ void luaD_call (lua_State *L, StkId func, int nResults);
 void luaD_callTM (lua_State *L, Closure *f, int nParams, int nResults);
 void luaD_checkstack (lua_State *L, int n);
 
+void luaD_error (lua_State *L, const char *s);
 void luaD_breakrun (lua_State *L, int errcode);
 int luaD_runprotected (lua_State *L, void (*f)(lua_State *, void *), void *ud);
 

+ 3 - 3
lmem.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lmem.c,v 1.42 2000/12/28 12:55:41 roberto Exp roberto $
+** $Id: lmem.c,v 1.43 2001/01/19 13:20:30 roberto Exp roberto $
 ** Interface to Memory Manager
 ** See Copyright Notice in lua.h
 */
@@ -134,7 +134,7 @@ void *luaM_growaux (lua_State *L, void *block, int *size, int size_elems,
   else if (*size >= limit/2) {  /* cannot double it? */
     if (*size < limit - MINPOWER2)  /* try something smaller... */
       newsize = limit;  /* still have at least MINPOWER2 free places */
-    else lua_error(L, errormsg);
+    else luaD_error(L, errormsg);
   }
   newblock = luaM_realloc(L, block, (luint32)(*size)*(luint32)size_elems,
                                     (luint32)newsize*(luint32)size_elems);
@@ -152,7 +152,7 @@ void *luaM_realloc (lua_State *L, void *block, luint32 oldsize, luint32 size) {
     block = NULL;
   }
   else if (size >= MAX_SIZET)
-    lua_error(L, "memory allocation error: block too big");
+    luaD_error(L, "memory allocation error: block too big");
   else {
     block = basicrealloc(block, oldsize, size);
     if (block == NULL) {

+ 3 - 2
lobject.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lobject.c,v 1.58 2000/12/28 12:55:41 roberto Exp roberto $
+** $Id: lobject.c,v 1.59 2001/01/19 13:20:30 roberto Exp roberto $
 ** Some generic functions over Lua objects
 ** See Copyright Notice in lua.h
 */
@@ -12,6 +12,7 @@
 
 #include "lua.h"
 
+#include "ldo.h"
 #include "lmem.h"
 #include "lobject.h"
 #include "lstate.h"
@@ -85,7 +86,7 @@ void luaO_verror (lua_State *L, const char *fmt, ...) {
   va_start(argp, fmt);
   vsprintf(buff, fmt, argp);
   va_end(argp);
-  lua_error(L, buff);
+  luaD_error(L, buff);
 }
 
 

+ 38 - 22
lstate.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.c,v 1.51 2001/01/19 13:20:30 roberto Exp roberto $
+** $Id: lstate.c,v 1.52 2001/01/22 18:01:38 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -22,6 +22,7 @@
 #ifdef LUA_DEBUG
 static lua_State *lua_state = NULL;
 void luaB_opentests (lua_State *L);
+int islocked = 0;
 #endif
 
 
@@ -44,6 +45,9 @@ struct Sopen {
 };
 
 
+static void close_state (lua_State *L);
+
+
 /*
 ** open parts that may cause memory-allocation errors
 */
@@ -80,12 +84,13 @@ static void f_luaopen (lua_State *L, void *ud) {
     G(L)->sizeref = 0;
     G(L)->refFree = NONEXT;
     G(L)->nblocks = sizeof(lua_State) + sizeof(global_State);
-    G(L)->GCthreshold = MAX_INT;  /* to avoid GC during pre-definitions */
     luaD_init(L, so->stacksize);  /* init stack */
     L->gt = luaH_new(L, 10);  /* table of globals */
     luaS_init(L);
     luaX_init(L);
     luaT_init(L);
+    G(L)->GCthreshold = 4*G(L)->nblocks;
+    LUA_EXIT;  /* temporary exit to use the API */
     lua_newtable(L);
     lua_ref(L, 1);  /* create registry */
     lua_register(L, LUA_ERRORMESSAGE, errormessage);
@@ -94,37 +99,41 @@ static void f_luaopen (lua_State *L, void *ud) {
     if (lua_state == NULL) lua_state = L;  /* keep first state to be opened */
     lua_assert(lua_gettop(L) == 0);
 #endif
-    G(L)->GCthreshold = 2*G(L)->nblocks;
+    LUA_ENTRY;  /* go back inside */
   }
 }
 
 
 LUA_API lua_State *lua_open (lua_State *OL, int stacksize) {
   struct Sopen so;
-  lua_State *L = luaM_new(OL, lua_State);
-  if (L == NULL) return NULL;  /* memory allocation error */
-  L->G = NULL;
-  L->stack = NULL;
-  L->stacksize = 0;
-  L->errorJmp = NULL;
-  L->callhook = NULL;
-  L->linehook = NULL;
-  L->allowhooks = 1;
-  L->next = L->previous = L;
-  so.stacksize = stacksize;
-  so.L = OL;
-  if (luaD_runprotected(L, f_luaopen, &so) != 0) {
-    /* memory allocation error: free partial state */
-    lua_close(L);
-    return NULL;
+  lua_State *L;
+  LUA_ENTRY;
+  L = luaM_new(OL, lua_State);
+  if (L) {  /* allocation OK? */
+    L->G = NULL;
+    L->stack = NULL;
+    L->stacksize = 0;
+    L->errorJmp = NULL;
+    L->callhook = NULL;
+    L->linehook = NULL;
+    L->allowhooks = 1;
+    L->next = L->previous = L;
+    so.stacksize = stacksize;
+    so.L = OL;
+    if (luaD_runprotected(L, f_luaopen, &so) != 0) {
+      /* memory allocation error: free partial state */
+      close_state(L);
+      L = NULL;
+    }
   }
+  LUA_EXIT;
   return L;
 }
 
 
-LUA_API void lua_close (lua_State *L) {
-  lua_State *L1 = L->next;  /* any surviving thread (if there is one) */
-  lua_assert(L != lua_state || lua_gettop(L) == 0);
+static void close_state (lua_State *L) {
+  lua_State *L1;
+  L1 = L->next;  /* any surviving thread (if there is one) */
   if (L1 == L) L1 = NULL;  /* no surviving threads */
   if (L1 != NULL) {  /* are there other threads? */
     lua_assert(L->previous != L);
@@ -144,6 +153,13 @@ LUA_API void lua_close (lua_State *L) {
   }
   luaM_freearray(L1, L->stack, L->stacksize, TObject);
   luaM_freelem(L1, L, lua_State);
+}
+
+LUA_API void lua_close (lua_State *L) {
+  lua_assert(L != lua_state || lua_gettop(L) == 0);
+  LUA_ENTRY;
+  close_state(L);
+  LUA_EXIT;
   lua_assert(L != lua_state || memdebug_numblocks == 0);
   lua_assert(L != lua_state || memdebug_total == 0);
 }

+ 21 - 1
lstate.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.h,v 1.44 2001/01/19 13:20:30 roberto Exp roberto $
+** $Id: lstate.h,v 1.45 2001/01/22 18:01:38 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -13,6 +13,26 @@
 
 
 
+#ifdef LUA_DEBUG
+extern int islocked;
+#define LUA_ENTRY	lua_assert(islocked++ == 0)
+#define LUA_EXIT	lua_assert(--islocked == 0)
+#endif
+
+
+/*
+** macros that control all entries and exits from Lua core machine
+** (mainly for thread syncronization)
+*/
+#ifndef LUA_ENTRY
+#define LUA_ENTRY
+#endif
+
+#ifndef LUA_EXIT
+#define LUA_EXIT
+#endif
+
+
 typedef TObject *StkId;  /* index to stack elements */
 
 

+ 5 - 4
ltable.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltable.c,v 1.64 2001/01/18 15:59:09 roberto Exp roberto $
+** $Id: ltable.c,v 1.65 2001/01/19 13:20:30 roberto Exp roberto $
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 */
@@ -20,6 +20,7 @@
 
 #include "lua.h"
 
+#include "ldo.h"
 #include "lmem.h"
 #include "lobject.h"
 #include "lstate.h"
@@ -112,7 +113,7 @@ Node *luaH_next (lua_State *L, const Hash *t, const TObject *key) {
   else {
     const TObject *v = luaH_get(t, key);
     if (v == &luaO_nilobject)
-      lua_error(L, "invalid key for `next'");
+      luaD_error(L, "invalid key for `next'");
     i = (int)(((const char *)v -
                (const char *)(&t->node[0].val)) / sizeof(Node)) + 1;
   }
@@ -152,7 +153,7 @@ void luaH_remove (Hash *t, TObject *key) {
 static void setnodevector (lua_State *L, Hash *t, luint32 size) {
   int i;
   if (size > MAX_INT)
-    lua_error(L, "table overflow");
+    luaD_error(L, "table overflow");
   t->node = luaM_newvector(L, size, Node);
   for (i=0; i<(int)size; i++) {
     setnilvalue(&t->node[i].key);
@@ -259,7 +260,7 @@ static TObject *luaH_setany (lua_State *L, Hash *t, const TObject *key) {
   Node *mp = luaH_mainposition(t, key);
   Node *n = mp;
   if (!mp)
-    lua_error(L, "table index is nil");
+    luaD_error(L, "table index is nil");
   do {  /* check whether `key' is somewhere in the chain */
     if (luaO_equalObj(key, &n->key))
       return &n->val;  /* that's all */

+ 15 - 4
ltm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltm.c,v 1.60 2001/01/18 15:59:09 roberto Exp roberto $
+** $Id: ltm.c,v 1.61 2001/01/19 13:20:30 roberto Exp roberto $
 ** Tag methods
 ** See Copyright Notice in lua.h
 */
@@ -84,10 +84,14 @@ void luaT_init (lua_State *L) {
 
 
 LUA_API int lua_newtag (lua_State *L) {
+  int tag;
+  LUA_ENTRY;
   luaM_growvector(L, G(L)->TMtable, G(L)->ntag, G(L)->sizeTM, struct TM,
                   MAX_INT, "tag table overflow");
   init_entry(L, G(L)->ntag);
-  return G(L)->ntag++;
+  tag = G(L)->ntag++;
+  LUA_EXIT;
+  return tag;
 }
 
 
@@ -104,12 +108,14 @@ void luaT_realtag (lua_State *L, int tag) {
 
 LUA_API int lua_copytagmethods (lua_State *L, int tagto, int tagfrom) {
   int e;
+  LUA_ENTRY;
   checktag(L, tagto);
   checktag(L, tagfrom);
   for (e=0; e<TM_N; e++) {
     if (luaT_validevent(tagto, e))
       luaT_gettm(G(L), tagto, e) = luaT_gettm(G(L), tagfrom, e);
   }
+  LUA_EXIT;
   return tagto;
 }
 
@@ -126,6 +132,7 @@ int luaT_tag (const TObject *o) {
 
 LUA_API void lua_gettagmethod (lua_State *L, int t, const char *event) {
   int e;
+  LUA_ENTRY;
   e = luaI_checkevent(L, event, t);
   checktag(L, t);
   if (luaT_validevent(t, e) && luaT_gettm(G(L), t, e)) {
@@ -134,11 +141,14 @@ LUA_API void lua_gettagmethod (lua_State *L, int t, const char *event) {
   else
     setnilvalue(L->top);
   incr_top;
+  LUA_EXIT;
 }
 
 
 LUA_API void lua_settagmethod (lua_State *L, int t, const char *event) {
-  int e = luaI_checkevent(L, event, t);
+  int e;
+  LUA_ENTRY;
+  e = luaI_checkevent(L, event, t);
   checktag(L, t);
   if (!luaT_validevent(t, e))
     luaO_verror(L, "cannot change `%.20s' tag method for type `%.20s'%.20s",
@@ -153,8 +163,9 @@ LUA_API void lua_settagmethod (lua_State *L, int t, const char *event) {
       luaT_gettm(G(L), t, e) = clvalue(L->top - 1);
       break;
     default:
-      lua_error(L, "tag method must be a function (or nil)");
+      luaD_error(L, "tag method must be a function (or nil)");
   }
   L->top--;
+  LUA_EXIT;
 }
 

+ 10 - 9
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 1.154 2001/01/18 15:59:09 roberto Exp roberto $
+** $Id: lvm.c,v 1.155 2001/01/19 13:20:30 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -219,7 +219,8 @@ static int call_binTM (lua_State *L, StkId top, TMS event) {
         return 0;  /* error */
     }
   }
-  lua_pushstring(L, luaT_eventname[event]);
+  setsvalue(L->top, luaS_new(L, luaT_eventname[event]));
+  incr_top;
   luaD_callTM(L, tm, 3, 1);
   return 1;
 }
@@ -287,7 +288,7 @@ void luaV_strconc (lua_State *L, int total, StkId top) {
         tl += tsvalue(top-n-1)->len;
         n++;
       }
-      if (tl > MAX_SIZET) lua_error(L, "string size overflow");
+      if (tl > MAX_SIZET) luaD_error(L, "string size overflow");
       buffer = luaO_openspace(L, tl);
       tl = 0;
       for (i=n; i>0; i--) {  /* concat all strings */
@@ -520,7 +521,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
       }
       case OP_POW: {
         if (!call_binTM(L, top, TM_POW))
-          lua_error(L, "undefined operation");
+          luaD_error(L, "undefined operation");
         top--;
         break;
       }
@@ -606,11 +607,11 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
       }
       case OP_FORPREP: {
         if (tonumber(top-1))
-          lua_error(L, "`for' step must be a number");
+          luaD_error(L, "`for' step must be a number");
         if (tonumber(top-2))
-          lua_error(L, "`for' limit must be a number");
+          luaD_error(L, "`for' limit must be a number");
         if (tonumber(top-3))
-          lua_error(L, "`for' initial value must be a number");
+          luaD_error(L, "`for' initial value must be a number");
         if (nvalue(top-1) > 0 ?
             nvalue(top-3) > nvalue(top-2) :
             nvalue(top-3) < nvalue(top-2)) {  /* `empty' loop? */
@@ -623,7 +624,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
         lua_assert(ttype(top-1) == LUA_TNUMBER);
         lua_assert(ttype(top-2) == LUA_TNUMBER);
         if (ttype(top-3) != LUA_TNUMBER)
-          lua_error(L, "`for' index must be a number");
+          luaD_error(L, "`for' index must be a number");
         nvalue(top-3) += nvalue(top-1);  /* increment index */
         if (nvalue(top-1) > 0 ?
             nvalue(top-3) > nvalue(top-2) :
@@ -636,7 +637,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
       case OP_LFORPREP: {
         Node *node;
         if (ttype(top-1) != LUA_TTABLE)
-          lua_error(L, "`for' table must be a table");
+          luaD_error(L, "`for' table must be a table");
         node = luaH_next(L, hvalue(top-1), &luaO_nilobject);
         if (node == NULL) {  /* `empty' loop? */
           top--;  /* remove table */