فهرست منبع

macros LUA_ENTRY/LUA_EXIT to control exclusive access to Lua core

Roberto Ierusalimschy 25 سال پیش
والد
کامیت
71ae4801d6
11فایلهای تغییر یافته به همراه420 افزوده شده و 149 حذف شده
  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 */