Selaa lähdekoodia

thead-specific state separated from "global" state

Roberto Ierusalimschy 24 vuotta sitten
vanhempi
commit
4ac58853dc
19 muutettua tiedostoa jossa 268 lisäystä ja 257 poistoa
  1. 25 25
      lapi.c
  2. 8 8
      lcode.c
  3. 18 19
      ldebug.c
  4. 8 8
      ldo.c
  5. 5 5
      lfunc.c
  6. 42 43
      lgc.c
  7. 9 9
      llex.c
  8. 4 4
      lmem.c
  9. 6 6
      lobject.c
  10. 14 16
      lobject.h
  11. 7 8
      lparser.c
  12. 41 36
      lstate.c
  13. 23 12
      lstate.h
  14. 14 15
      lstring.c
  15. 5 5
      ltable.c
  16. 3 2
      ltests.c
  17. 17 17
      ltm.c
  18. 4 4
      ltm.h
  19. 15 15
      lvm.c

+ 25 - 25
lapi.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 1.116 2001/01/10 18:56:11 roberto Exp roberto $
+** $Id: lapi.c,v 1.117 2001/01/18 15:59:09 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -230,7 +230,7 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
 
 LUA_API void lua_pushusertag (lua_State *L, void *u, int tag) {
   /* ORDER LUA_T */
-  if (!(tag == LUA_ANYTAG || tag == LUA_TUSERDATA || validtag(tag)))
+  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);
@@ -261,14 +261,14 @@ LUA_API void lua_gettable (lua_State *L, int index) {
 
 LUA_API void lua_rawget (lua_State *L, int index) {
   StkId t = Index(L, index);
-  LUA_ASSERT(ttype(t) == LUA_TTABLE, "table expected");
+  lua_assert(ttype(t) == LUA_TTABLE);
   setobj(L->top - 1, luaH_get(hvalue(t), L->top - 1));
 }
 
 
 LUA_API void lua_rawgeti (lua_State *L, int index, int n) {
   StkId o = Index(L, index);
-  LUA_ASSERT(ttype(o) == LUA_TTABLE, "table expected");
+  lua_assert(ttype(o) == LUA_TTABLE);
   setobj(L->top, luaH_getnum(hvalue(o), n));
   api_incr_top(L);
 }
@@ -284,9 +284,9 @@ LUA_API int lua_getref (lua_State *L, int ref) {
   if (ref == LUA_REFNIL) {
     setnilvalue(L->top);
   }
-  else if (0 <= ref && ref < L->nref &&
-          (L->refArray[ref].st == LOCK || L->refArray[ref].st == HOLD)) {
-    setobj(L->top, &L->refArray[ref].o);
+  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);
   }
   else
     return 0;
@@ -324,7 +324,7 @@ LUA_API void lua_settable (lua_State *L, int index) {
 
 LUA_API void lua_rawset (lua_State *L, int index) {
   StkId t = Index(L, index);
-  LUA_ASSERT(ttype(t) == LUA_TTABLE, "table expected");
+  lua_assert(ttype(t) == LUA_TTABLE);
   setobj(luaH_set(L, hvalue(t), L->top-2), (L->top-1));
   L->top -= 2;
 }
@@ -332,7 +332,7 @@ LUA_API void lua_rawset (lua_State *L, int index) {
 
 LUA_API void lua_rawseti (lua_State *L, int index, int n) {
   StkId o = Index(L, index);
-  LUA_ASSERT(ttype(o) == LUA_TTABLE, "table expected");
+  lua_assert(ttype(o) == LUA_TTABLE);
   setobj(luaH_setnum(L, hvalue(o), n), (L->top-1));
   L->top--;
 }
@@ -340,7 +340,7 @@ LUA_API void lua_rawseti (lua_State *L, int index, int n) {
 
 LUA_API void lua_setglobals (lua_State *L) {
   StkId newtable = --L->top;
-  LUA_ASSERT(ttype(newtable) == LUA_TTABLE, "table expected");
+  lua_assert(ttype(newtable) == LUA_TTABLE);
   L->gt = hvalue(newtable);
 }
 
@@ -350,17 +350,17 @@ LUA_API int lua_ref (lua_State *L,  int lock) {
   if (ttype(L->top-1) == LUA_TNIL)
     ref = LUA_REFNIL;
   else {
-    if (L->refFree != NONEXT) {  /* is there a free place? */
-      ref = L->refFree;
-      L->refFree = L->refArray[ref].st;
+    if (G(L)->refFree != NONEXT) {  /* is there a free place? */
+      ref = G(L)->refFree;
+      G(L)->refFree = G(L)->refArray[ref].st;
     }
     else {  /* no more free places */
-      luaM_growvector(L, L->refArray, L->nref, L->sizeref, struct Ref,
+      luaM_growvector(L, G(L)->refArray, G(L)->nref, G(L)->sizeref, struct Ref,
                       MAX_INT, "reference table overflow");
-      ref = L->nref++;
+      ref = G(L)->nref++;
     }
-    setobj(&L->refArray[ref].o, L->top-1);
-    L->refArray[ref].st = lock ? LOCK : HOLD;
+    setobj(&G(L)->refArray[ref].o, L->top-1);
+    G(L)->refArray[ref].st = lock ? LOCK : HOLD;
   }
   L->top--;
   return ref;
@@ -386,18 +386,18 @@ 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(L->GCthreshold);
+  return GCscale(G(L)->GCthreshold);
 }
 
 LUA_API int lua_getgccount (lua_State *L) {
-  return GCscale(L->nblocks);
+  return GCscale(G(L)->nblocks);
 }
 
 LUA_API void lua_setgcthreshold (lua_State *L, int newthreshold) {
   if (newthreshold > GCscale(ULONG_MAX))
-    L->GCthreshold = ULONG_MAX;
+    G(L)->GCthreshold = ULONG_MAX;
   else
-    L->GCthreshold = GCunscale(newthreshold);
+    G(L)->GCthreshold = GCunscale(newthreshold);
   luaC_checkGC(L);
 }
 
@@ -424,9 +424,9 @@ LUA_API void lua_settag (lua_State *L, int tag) {
 
 LUA_API void lua_unref (lua_State *L, int ref) {
   if (ref >= 0) {
-    LUA_ASSERT(ref < L->nref && L->refArray[ref].st < 0, "invalid ref");
-    L->refArray[ref].st = L->refFree;
-    L->refFree = ref;
+    lua_assert(ref < G(L)->nref && G(L)->refArray[ref].st < 0);
+    G(L)->refArray[ref].st = G(L)->refFree;
+    G(L)->refFree = ref;
   }
 }
 
@@ -434,7 +434,7 @@ LUA_API void lua_unref (lua_State *L, int ref) {
 LUA_API int lua_next (lua_State *L, int index) {
   StkId t = luaA_index(L, index);
   Node *n;
-  LUA_ASSERT(ttype(t) == LUA_TTABLE, "table expected");
+  lua_assert(ttype(t) == LUA_TTABLE);
   n = luaH_next(L, hvalue(t), luaA_index(L, -1));
   if (n) {
     setobj(L->top-1, key(n));

+ 8 - 8
lcode.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lcode.c,v 1.55 2000/12/28 12:55:41 roberto Exp roberto $
+** $Id: lcode.c,v 1.56 2001/01/15 16:13:24 roberto Exp roberto $
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -189,7 +189,7 @@ void luaK_storevar (LexState *ls, const expdesc *var) {
       luaK_code2(fs, OP_SETTABLE, 3, 3);
       break;
     default:
-      LUA_INTERNALERROR("invalid var kind to store");
+      lua_assert(0);  /* invalid var kind to store */
   }
 }
 
@@ -205,7 +205,7 @@ static OpCode invertjump (OpCode op) {
     case OP_JMPT: case OP_JMPONT:  return OP_JMPF;
     case OP_JMPF: case OP_JMPONF:  return OP_JMPT;
     default:
-      LUA_INTERNALERROR("invalid jump instruction");
+      lua_assert(0);  /* invalid jump instruction */
       return OP_JMP;  /* to avoid warnings */
   }
 }
@@ -280,7 +280,7 @@ static void luaK_testgo (FuncState *fs, expdesc *v, int invert, OpCode jump) {
   discharge1(fs, v);
   prevpos = fs->pc-1;
   previous = &fs->f->code[prevpos];
-  LUA_ASSERT(*previous==previous_instruction(fs), "no jump allowed here");
+  lua_assert(*previous==previous_instruction(fs));  /* no jump allowed here */
   if (!ISJUMP(GET_OPCODE(*previous)))
     prevpos = luaK_code1(fs, jump, NO_JUMP);
   else {  /* last instruction is already a jump */
@@ -398,14 +398,14 @@ void luaK_posfix (LexState *ls, BinOpr op, expdesc *v1, expdesc *v2) {
   FuncState *fs = ls->fs;
   switch (op) {
     case OPR_AND: {
-      LUA_ASSERT(v1->u.l.t == NO_JUMP, "list must be closed");
+      lua_assert(v1->u.l.t == NO_JUMP);  /* list must be closed */
       discharge1(fs, v2);
       v1->u.l.t = v2->u.l.t;
       luaK_concat(fs, &v1->u.l.f, v2->u.l.f);
       break;
     }
     case OPR_OR: {
-      LUA_ASSERT(v1->u.l.f == NO_JUMP, "list must be closed");
+      lua_assert(v1->u.l.f == NO_JUMP);  /* list must be closed */
       discharge1(fs, v2);
       v1->u.l.f = v2->u.l.f;
       luaK_concat(fs, &v1->u.l.t, v2->u.l.t);
@@ -622,11 +622,11 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
     case OP_GETINDEXED:
     case OP_TAILCALL:
     case OP_ADDI: {
-      LUA_INTERNALERROR("instruction used only for optimizations");
+      lua_assert(0);  /* instruction used only for optimizations */
       break;
     }
     default: {
-      LUA_ASSERT(delta != VD, "invalid delta");
+      lua_assert(delta != VD);
       break;
     }
   }

+ 18 - 19
ldebug.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldebug.c,v 1.52 2000/12/26 18:46:09 roberto Exp roberto $
+** $Id: ldebug.c,v 1.53 2001/01/18 15:59:09 roberto Exp roberto $
 ** Debug Interface
 ** See Copyright Notice in lua.h
 */
@@ -96,20 +96,20 @@ int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) {
   refi = prefi ? *prefi : 0;
   if (lineinfo[refi] < 0)
     refline += -lineinfo[refi++]; 
-  LUA_ASSERT(lineinfo[refi] >= 0, "invalid line info");
+  lua_assert(lineinfo[refi] >= 0);
   while (lineinfo[refi] > pc) {
     refline--;
     refi--;
     if (lineinfo[refi] < 0)
       refline -= -lineinfo[refi--]; 
-    LUA_ASSERT(lineinfo[refi] >= 0, "invalid line info");
+    lua_assert(lineinfo[refi] >= 0);
   }
   for (;;) {
     int nextline = refline + 1;
     int nextref = refi + 1;
     if (lineinfo[nextref] < 0)
       nextline += -lineinfo[nextref++]; 
-    LUA_ASSERT(lineinfo[nextref] >= 0, "invalid line info");
+    lua_assert(lineinfo[nextref] >= 0);
     if (lineinfo[nextref] > pc)
       break;
     refline = nextline;
@@ -122,7 +122,7 @@ int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) {
 
 static int currentpc (StkId f) {
   CallInfo *ci = infovalue(f);
-  LUA_ASSERT(isLmark(f), "function has no pc");
+  lua_assert(isLmark(f));
   if (ci->pc)
     return (*ci->pc - ci->func->f.l->code) - 1;
   else
@@ -204,13 +204,13 @@ static void funcinfo (lua_State *L, lua_Debug *ar, StkId func) {
 }
 
 
-static const char *travtagmethods (lua_State *L, const TObject *o) {
+static const char *travtagmethods (global_State *G, const TObject *o) {
   if (ttype(o) == LUA_TFUNCTION) {
     int e;
     for (e=0; e<TM_N; e++) {
       int t;
-      for (t=0; t<L->ntag; t++)
-        if (clvalue(o) == luaT_gettm(L, t, e))
+      for (t=0; t<G->ntag; t++)
+        if (clvalue(o) == luaT_gettm(G, t, e))
           return luaT_eventname[e];
     }
   }
@@ -237,7 +237,7 @@ static void getname (lua_State *L, StkId f, lua_Debug *ar) {
   if ((ar->name = travglobals(L, &o)) != NULL)
     ar->namewhat = "global";
   /* not found: try tag methods */
-  else if ((ar->name = travtagmethods(L, &o)) != NULL)
+  else if ((ar->name = travtagmethods(G(L), &o)) != NULL)
     ar->namewhat = "tag-method";
   else ar->namewhat = "";  /* not found at all */
 }
@@ -308,22 +308,22 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos) {
     top++;  /* `arg' */
   while (pc < lastpc) {
     const Instruction i = code[pc++];
-    LUA_ASSERT(0 <= top && top <= pt->maxstacksize, "wrong stack");
+    lua_assert(0 <= top && top <= pt->maxstacksize);
     switch (GET_OPCODE(i)) {
       case OP_RETURN: {
-        LUA_ASSERT(top >= GETARG_U(i), "wrong stack");
+        lua_assert(top >= GETARG_U(i));
         top = GETARG_U(i);
         break;
       }
       case OP_TAILCALL: {
-        LUA_ASSERT(top >= GETARG_A(i), "wrong stack");
+        lua_assert(top >= GETARG_A(i));
         top = GETARG_B(i);
         break;
       }
       case OP_CALL: {
         int nresults = GETARG_B(i);
         if (nresults == MULT_RET) nresults = 1;
-        LUA_ASSERT(top >= GETARG_A(i), "wrong stack");
+        lua_assert(top >= GETARG_A(i));
         top = pushpc(stack, pc, GETARG_A(i), nresults);
         break;
       }
@@ -368,10 +368,9 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos) {
       }
       default: {
         OpCode op = GET_OPCODE(i);
-        LUA_ASSERT(luaK_opproperties[op].push != VD,
-                   "invalid opcode for default");
+        lua_assert(luaK_opproperties[op].push != VD);
         top -= (int)luaK_opproperties[op].pop;
-        LUA_ASSERT(top >= 0, "wrong stack");
+        lua_assert(top >= 0);
         top = pushpc(stack, pc, top, luaK_opproperties[op].push);
       }
     }
@@ -389,7 +388,7 @@ static const char *getobjname (lua_State *L, StkId obj, const char **name) {
     int pc = currentpc(func);
     int stackpos = obj - (func+1);  /* func+1 == function base */
     Instruction i = luaG_symbexec(p, pc, stackpos);
-    LUA_ASSERT(pc != -1, "function must be active");
+    lua_assert(pc != -1);
     switch (GET_OPCODE(i)) {
       case OP_GETGLOBAL: {
         *name = p->kstr[GETARG_U(i)]->str;
@@ -397,7 +396,7 @@ static const char *getobjname (lua_State *L, StkId obj, const char **name) {
       }
       case OP_GETLOCAL: {
         *name = luaF_getlocalname(p, GETARG_U(i)+1, pc);
-        LUA_ASSERT(*name, "local must exist");
+        lua_assert(*name);
         return "local";
       }
       case OP_PUSHSELF:
@@ -449,7 +448,7 @@ void luaG_typeerror (lua_State *L, StkId o, const char *op) {
 
 void luaG_binerror (lua_State *L, StkId p1, int t, const char *op) {
   if (ttype(p1) == t) p1++;
-  LUA_ASSERT(ttype(p1) != t, "must be an error");
+  lua_assert(ttype(p1) != t);
   luaG_typeerror(L, p1, op);
 }
 

+ 8 - 8
ldo.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.c,v 1.113 2001/01/10 18:56:11 roberto Exp roberto $
+** $Id: ldo.c,v 1.114 2001/01/18 15:59:09 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -55,7 +55,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, "wrong stack limit");
+      lua_assert(L->stack_last == L->stack+L->stacksize-1);
       lua_error(L, "stack overflow");
     }
   }
@@ -95,7 +95,7 @@ static void dohook (lua_State *L, lua_Debug *ar, lua_Hook hook) {
   luaD_checkstack(L, LUA_MINSTACK);  /* ensure minimum stack size */
   L->allowhooks = 0;  /* cannot call hooks inside a hook */
   (*hook)(L, ar);
-  LUA_ASSERT(L->allowhooks == 0, "invalid allow");
+  lua_assert(L->allowhooks == 0);
   L->allowhooks = 1;
   L->top = old_top;
   L->Cbase = old_Cbase;
@@ -161,7 +161,7 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
   Closure *cl;
   if (ttype(func) != LUA_TFUNCTION) {
     /* `func' is not a function; check the `function' tag method */
-    Closure *tm = luaT_gettmbyObj(L, func, TM_FUNCTION);
+    Closure *tm = luaT_gettmbyObj(G(L), func, TM_FUNCTION);
     if (tm == NULL)
       luaG_typeerror(L, func, "call");
     luaD_openstack(L, func);
@@ -177,7 +177,7 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
                            luaV_execute(L, cl, func+1));
   if (callhook)  /* same hook that was active at entry */
     luaD_callHook(L, func, callhook, "return");
-  LUA_ASSERT(ttype(func) == LUA_TMARK, "invalid tag");
+  lua_assert(ttype(func) == LUA_TMARK);
   /* move results to `func' (to erase parameters and function) */
   if (nResults == LUA_MULTRET) {
     while (firstResult < L->top)  /* copy all results */
@@ -244,12 +244,12 @@ static int protectedparser (lua_State *L, ZIO *z, int bin) {
   int status;
   p.z = z; p.bin = bin;
   luaC_checkGC(L);
-  old_blocks = L->nblocks;
+  old_blocks = G(L)->nblocks;
   status = luaD_runprotected(L, f_parser, &p);
   if (status == 0) {
     /* add new memory to threshold (as it probably will stay) */
-    LUA_ASSERT(L->nblocks >= old_blocks, "cannot reduce memory usage here");
-    L->GCthreshold += (L->nblocks - old_blocks);
+    lua_assert(G(L)->nblocks >= old_blocks);
+    G(L)->GCthreshold += (G(L)->nblocks - old_blocks);
   }
   else if (status == LUA_ERRRUN)  /* an error occurred: correct error code */
     status = LUA_ERRSYNTAX;

+ 5 - 5
lfunc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lfunc.c,v 1.35 2000/12/04 18:33:40 roberto Exp roberto $
+** $Id: lfunc.c,v 1.36 2000/12/28 12:55:41 roberto Exp roberto $
 ** Auxiliary functions to manipulate prototypes and closures
 ** See Copyright Notice in lua.h
 */
@@ -19,8 +19,8 @@
 
 Closure *luaF_newclosure (lua_State *L, int nelems) {
   Closure *c = (Closure *)luaM_malloc(L, sizeclosure(nelems));
-  c->next = L->rootcl;
-  L->rootcl = c;
+  c->next = G(L)->rootcl;
+  G(L)->rootcl = c;
   c->mark = c;
   c->nupvalues = nelems;
   return c;
@@ -47,8 +47,8 @@ Proto *luaF_newproto (lua_State *L) {
   f->locvars = NULL;
   f->lineDefined = 0;
   f->source = NULL;
-  f->next = L->rootproto;  /* chain in list of protos */
-  L->rootproto = f;
+  f->next = G(L)->rootproto;  /* chain in list of protos */
+  G(L)->rootproto = f;
   return f;
 }
 

+ 42 - 43
lgc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.c,v 1.75 2000/12/28 12:55:41 roberto Exp roberto $
+** $Id: lgc.c,v 1.76 2001/01/18 15:59:09 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -54,11 +54,11 @@ static void markstack (lua_State *L, GCState *st) {
 }
 
 
-static void marklock (lua_State *L, GCState *st) {
+static void marklock (global_State *G, GCState *st) {
   int i;
-  for (i=0; i<L->nref; i++) {
-    if (L->refArray[i].st == LOCK)
-      markobject(st, &L->refArray[i].o);
+  for (i=0; i<G->nref; i++) {
+    if (G->refArray[i].st == LOCK)
+      markobject(st, &G->refArray[i].o);
   }
 }
 
@@ -73,12 +73,12 @@ static void markclosure (GCState *st, Closure *cl) {
 }
 
 
-static void marktagmethods (lua_State *L, GCState *st) {
+static void marktagmethods (global_State *G, GCState *st) {
   int e;
   for (e=0; e<TM_N; e++) {
     int t;
-    for (t=0; t<L->ntag; t++) {
-      Closure *cl = luaT_gettm(L, t, e);
+    for (t=0; t<G->ntag; t++) {
+      Closure *cl = luaT_gettm(G, t, e);
       if (cl) markclosure(st, cl);
     }
   }
@@ -113,9 +113,9 @@ static void markall (lua_State *L) {
   st.cmark = NULL;
   st.tmark = L->gt;  /* put table of globals in mark list */
   L->gt->mark = NULL;
-  marktagmethods(L, &st);  /* mark tag methods */
+  marktagmethods(G(L), &st);  /* mark tag methods */
   markstack(L, &st); /* mark stack objects */
-  marklock(L, &st); /* mark locked objects */
+  marklock(G(L), &st); /* mark locked objects */
   for (;;) {  /* mark tables and closures */
     if (st.cmark) {
       int i;
@@ -161,27 +161,26 @@ static int hasmark (const TObject *o) {
 /* 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->nref;
+static void invalidaterefs (global_State *G) {
+  int n = G->nref;
   int i;
   for (i=0; i<n; i++) {
-    struct Ref *r = &L->refArray[i];
+    struct Ref *r = &G->refArray[i];
     if (r->st == HOLD && !hasmark(&r->o))
       r->st = COLLECTED;
-    LUA_ASSERT((r->st == LOCK && hasmark(&r->o)) ||
+    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");
+               (r->st < n && VALIDLINK(L, G->refArray[r->st].st, n)));
   }
-  LUA_ASSERT(VALIDLINK(L, L->refFree, n), "inconsistent ref table");
+  lua_assert(VALIDLINK(L, G->refFree, n));
 }
 
 
 
 static void collectproto (lua_State *L) {
-  Proto **p = &L->rootproto;
+  Proto **p = &G(L)->rootproto;
   Proto *next;
   while ((next = *p) != NULL) {
     if (next->marked) {
@@ -197,7 +196,7 @@ static void collectproto (lua_State *L) {
 
 
 static void collectclosure (lua_State *L) {
-  Closure **p = &L->rootcl;
+  Closure **p = &G(L)->rootcl;
   Closure *next;
   while ((next = *p) != NULL) {
     if (ismarked(next)) {
@@ -213,7 +212,7 @@ static void collectclosure (lua_State *L) {
 
 
 static void collecttable (lua_State *L) {
-  Hash **p = &L->roottable;
+  Hash **p = &G(L)->roottable;
   Hash *next;
   while ((next = *p) != NULL) {
     if (ismarked(next)) {
@@ -236,8 +235,8 @@ static void checktab (lua_State *L, stringtable *tb) {
 
 static void collectstrings (lua_State *L, int all) {
   int i;
-  for (i=0; i<L->strt.size; i++) {  /* for each list */
-    TString **p = &L->strt.hash[i];
+  for (i=0; i<G(L)->strt.size; i++) {  /* for each list */
+    TString **p = &G(L)->strt.hash[i];
     TString *next;
     while ((next = *p) != NULL) {
       if (next->marked && !all) {  /* preserve? */
@@ -247,22 +246,22 @@ static void collectstrings (lua_State *L, int all) {
       } 
       else {  /* collect */
         *p = next->nexthash;
-        L->strt.nuse--;
+        G(L)->strt.nuse--;
         luaM_free(L, next, sizestring(next->len));
       }
     }
   }
-  checktab(L, &L->strt);
+  checktab(L, &G(L)->strt);
 }
 
 
 static void collectudata (lua_State *L, int all) {
   int i;
-  for (i=0; i<L->udt.size; i++) {  /* for each list */
-    TString **p = &L->udt.hash[i];
+  for (i=0; i<G(L)->udt.size; i++) {  /* for each list */
+    TString **p = &G(L)->udt.hash[i];
     TString *next;
     while ((next = *p) != NULL) {
-      LUA_ASSERT(next->marked <= 1, "udata cannot be fixed");
+      lua_assert(next->marked <= 1);
       if (next->marked && !all) {  /* preserve? */
         next->marked = 0;
         p = &next->nexthash;
@@ -270,28 +269,28 @@ static void collectudata (lua_State *L, int all) {
       else {  /* collect */
         int tag = next->u.d.tag;
         *p = next->nexthash;
-        next->nexthash = L->TMtable[tag].collected;  /* chain udata */
-        L->TMtable[tag].collected = next;
-        L->udt.nuse--;
+        next->nexthash = G(L)->TMtable[tag].collected;  /* chain udata */
+        G(L)->TMtable[tag].collected = next;
+        G(L)->udt.nuse--;
       }
     }
   }
-  checktab(L, &L->udt);
+  checktab(L, &G(L)->udt);
 }
 
 
 #define MINBUFFER	256
 static void checkMbuffer (lua_State *L) {
-  if (L->Mbuffsize > MINBUFFER*2) {  /* is buffer too big? */
-    size_t newsize = L->Mbuffsize/2;  /* still larger than MINBUFFER */
-    luaM_reallocvector(L, L->Mbuffer, L->Mbuffsize, newsize, char);
-    L->Mbuffsize = newsize;
+  if (G(L)->Mbuffsize > MINBUFFER*2) {  /* is buffer too big? */
+    size_t newsize = G(L)->Mbuffsize/2;  /* still larger than MINBUFFER */
+    luaM_reallocvector(L, G(L)->Mbuffer, G(L)->Mbuffsize, newsize, char);
+    G(L)->Mbuffsize = newsize;
   }
 }
 
 
 static void callgcTM (lua_State *L, const TObject *obj) {
-  Closure *tm = luaT_gettmbyObj(L, obj, TM_GC);
+  Closure *tm = luaT_gettmbyObj(G(L), obj, TM_GC);
   if (tm != NULL) {
     int oldah = L->allowhooks;
     L->allowhooks = 0;  /* stop debug hooks during GC tag methods */
@@ -307,12 +306,12 @@ static void callgcTM (lua_State *L, const TObject *obj) {
 
 static void callgcTMudata (lua_State *L) {
   int tag;
-  L->GCthreshold = 2*L->nblocks;  /* avoid GC during tag methods */
-  for (tag=L->ntag-1; tag>=0; tag--) {  /* for each tag (in reverse order) */
+  G(L)->GCthreshold = 2*G(L)->nblocks;  /* avoid GC during tag methods */
+  for (tag=G(L)->ntag-1; tag>=0; tag--) {  /* for each tag (in reverse order) */
     TString *udata;
-    while ((udata = L->TMtable[tag].collected) != NULL) {
+    while ((udata = G(L)->TMtable[tag].collected) != NULL) {
       TObject obj;
-      L->TMtable[tag].collected = udata->nexthash;  /* remove it from list */
+      G(L)->TMtable[tag].collected = udata->nexthash;  /* remove it from list */
       setuvalue(&obj, udata);
       callgcTM(L, &obj);
       luaM_free(L, udata, sizeudata(udata->len));
@@ -333,16 +332,16 @@ void luaC_collect (lua_State *L, int all) {
 
 static void luaC_collectgarbage (lua_State *L) {
   markall(L);
-  invalidaterefs(L);  /* check unlocked references */
+  invalidaterefs(G(L));  /* check unlocked references */
   luaC_collect(L, 0);
   checkMbuffer(L);
-  L->GCthreshold = 2*L->nblocks;  /* set new threshold */
+  G(L)->GCthreshold = 2*G(L)->nblocks;  /* set new threshold */
   callgcTM(L, &luaO_nilobject);
 }
 
 
 void luaC_checkGC (lua_State *L) {
-  if (L->nblocks >= L->GCthreshold)
+  if (G(L)->nblocks >= G(L)->GCthreshold)
     luaC_collectgarbage(L);
 }
 

+ 9 - 9
llex.c

@@ -1,5 +1,5 @@
 /*
-** $Id: llex.c,v 1.74 2001/01/10 17:41:50 roberto Exp roberto $
+** $Id: llex.c,v 1.75 2001/01/15 18:07:56 roberto Exp roberto $
 ** Lexical Analyzer
 ** See Copyright Notice in lua.h
 */
@@ -35,7 +35,7 @@ void luaX_init (lua_State *L) {
   int i;
   for (i=0; i<NUM_RESERVED; i++) {
     TString *ts = luaS_new(L, token2string[i]);
-    LUA_ASSERT(strlen(token2string[i])+1 <= TOKEN_LEN, "incorrect token_len");
+    lua_assert(strlen(token2string[i])+1 <= TOKEN_LEN);
     ts->marked = (unsigned char)(RESERVEDMARK+i);  /* reserved word */
   }
 }
@@ -65,7 +65,7 @@ void luaX_error (LexState *ls, const char *s, int token) {
   char buff[TOKEN_LEN];
   luaX_token2str(token, buff);
   if (buff[0] == '\0')
-    luaX_syntaxerror(ls, s, ls->L->Mbuffer);
+    luaX_syntaxerror(ls, s, G(ls->L)->Mbuffer);
   else
     luaX_syntaxerror(ls, s, buff);
 }
@@ -123,10 +123,10 @@ void luaX_setinput (lua_State *L, LexState *LS, ZIO *z, TString *source) {
 /* use Mbuffer to store names, literal strings and numbers */
 
 #define EXTRABUFF	128
-#define checkbuffer(L, n, len)	if ((len)+(n) > L->Mbuffsize) \
+#define checkbuffer(L, n, len)	if ((len)+(n) > G(L)->Mbuffsize) \
                                   luaO_openspace(L, (len)+(n)+EXTRABUFF)
 
-#define save(L, c, l)	(L->Mbuffer[l++] = (char)c)
+#define save(L, c, l)	(G(L)->Mbuffer[l++] = (char)c)
 #define save_and_next(L, LS, l)  (save(L, LS->current, l), next(LS))
 
 
@@ -176,7 +176,7 @@ static void read_number (LexState *LS, int comma, SemInfo *seminfo) {
     }
   }
   save(L, '\0', l);
-  if (!luaO_str2d(L->Mbuffer, &seminfo->r))
+  if (!luaO_str2d(G(L)->Mbuffer, &seminfo->r))
     luaX_error(LS, "malformed number", TK_NUMBER);
 }
 
@@ -220,7 +220,7 @@ static void read_long_string (LexState *LS, SemInfo *seminfo) {
   } endloop:
   save_and_next(L, LS, l);  /* skip the second ']' */
   save(L, '\0', l);
-  seminfo->ts = luaS_newlstr(L, L->Mbuffer+2, l-5);
+  seminfo->ts = luaS_newlstr(L, G(L)->Mbuffer+2, l-5);
 }
 
 
@@ -272,7 +272,7 @@ static void read_string (LexState *LS, int del, SemInfo *seminfo) {
   }
   save_and_next(L, LS, l);  /* skip delimiter */
   save(L, '\0', l);
-  seminfo->ts = luaS_newlstr(L, L->Mbuffer+1, l-3);
+  seminfo->ts = luaS_newlstr(L, G(L)->Mbuffer+1, l-3);
 }
 
 
@@ -367,7 +367,7 @@ int luaX_lex (LexState *LS, SemInfo *seminfo) {
         }
         tname: {  /* identifier or reserved word */
           size_t l = readname(LS);
-          TString *ts = luaS_newlstr(LS->L, LS->L->Mbuffer, l);
+          TString *ts = luaS_newlstr(LS->L, G(LS->L)->Mbuffer, l);
           if (ts->marked >= RESERVEDMARK)  /* reserved word? */
             return ts->marked-RESERVEDMARK+FIRST_RESERVED;
           seminfo->ts = ts;

+ 4 - 4
lmem.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lmem.c,v 1.41 2000/12/26 18:46:09 roberto Exp roberto $
+** $Id: lmem.c,v 1.42 2000/12/28 12:55:41 roberto Exp roberto $
 ** Interface to Memory Manager
 ** See Copyright Notice in lua.h
 */
@@ -161,9 +161,9 @@ void *luaM_realloc (lua_State *L, void *block, luint32 oldsize, luint32 size) {
       else return NULL;  /* error before creating state! */
     }
   }
-  if (L) {
-    L->nblocks -= oldsize;
-    L->nblocks += size;
+  if (L && G(L)) {
+    G(L)->nblocks -= oldsize;
+    G(L)->nblocks += size;
   }
   return block;
 }

+ 6 - 6
lobject.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lobject.c,v 1.57 2000/12/04 18:33:40 roberto Exp roberto $
+** $Id: lobject.c,v 1.58 2000/12/28 12:55:41 roberto Exp roberto $
 ** Some generic functions over Lua objects
 ** See Copyright Notice in lua.h
 */
@@ -49,18 +49,18 @@ int luaO_equalObj (const TObject *t1, const TObject *t2) {
     case LUA_TFUNCTION:
       return clvalue(t1) == clvalue(t2);
     default:
-      LUA_ASSERT(ttype(t1) == LUA_TNIL, "invalid type");
+      lua_assert(ttype(t1) == LUA_TNIL);
       return 1; /* LUA_TNIL */
   }
 }
 
 
 char *luaO_openspace (lua_State *L, size_t n) {
-  if (n > L->Mbuffsize) {
-    luaM_reallocvector(L, L->Mbuffer, L->Mbuffsize, n, char);
-    L->Mbuffsize = n;
+  if (n > G(L)->Mbuffsize) {
+    luaM_reallocvector(L, G(L)->Mbuffer, G(L)->Mbuffsize, n, char);
+    G(L)->Mbuffsize = n;
   }
-  return L->Mbuffer;
+  return G(L)->Mbuffer;
 }
 
 

+ 14 - 16
lobject.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lobject.h,v 1.85 2000/12/28 12:55:41 roberto Exp roberto $
+** $Id: lobject.h,v 1.86 2001/01/18 15:59:09 roberto Exp roberto $
 ** Type definitions for Lua objects
 ** See Copyright Notice in lua.h
 */
@@ -15,11 +15,9 @@
 #ifdef LUA_DEBUG
 #undef NDEBUG
 #include <assert.h>
-#define LUA_INTERNALERROR(s)	assert(((void)s,0))
-#define LUA_ASSERT(c,s)		assert(((void)s,(c)))
+#define lua_assert(c)		assert(c)
 #else
-#define LUA_INTERNALERROR(s)	/* empty */
-#define LUA_ASSERT(c,s)		/* empty */
+#define lua_assert(c)		/* empty */
 #endif
 
 
@@ -67,27 +65,27 @@ typedef struct lua_TObject {
 
 /* Macros to set values */
 #define setnvalue(obj,x) \
-  { TObject *o=(obj); o->tt=LUA_TNUMBER; o->value.n=(x); }
+  { TObject *_o=(obj); _o->tt=LUA_TNUMBER; _o->value.n=(x); }
 
 #define setsvalue(obj,x) \
-  { TObject *o=(obj); struct TString *v=(x); \
-    o->tt=LUA_TSTRING; o->value.v=v; }
+  { TObject *_o=(obj); struct TString *_v=(x); \
+    _o->tt=LUA_TSTRING; _o->value.v=_v; }
 
 #define setuvalue(obj,x) \
-  { TObject *o=(obj); struct TString *v=(x); \
-    o->tt=LUA_TUSERDATA; o->value.v=v; }
+  { TObject *_o=(obj); struct TString *_v=(x); \
+    _o->tt=LUA_TUSERDATA; _o->value.v=_v; }
 
 #define setclvalue(obj,x) \
-  { TObject *o=(obj); struct Closure *v=(x); \
-    o->tt=LUA_TFUNCTION; o->value.v=v; }
+  { TObject *_o=(obj); struct Closure *_v=(x); \
+    _o->tt=LUA_TFUNCTION; _o->value.v=_v; }
 
 #define sethvalue(obj,x) \
-  { TObject *o=(obj); struct Hash *v=(x); \
-    o->tt=LUA_TTABLE; o->value.v=v; }
+  { TObject *_o=(obj); struct Hash *_v=(x); \
+    _o->tt=LUA_TTABLE; _o->value.v=_v; }
 
 #define setivalue(obj,x) \
-  { TObject *o=(obj); struct CallInfo *v=(x); \
-    o->tt=LUA_TMARK; o->value.v=v; }
+  { TObject *_o=(obj); struct CallInfo *_v=(x); \
+    _o->tt=LUA_TMARK; _o->value.v=_v; }
 
 #define setnilvalue(obj) { (obj)->tt=LUA_TNIL; }
 

+ 7 - 8
lparser.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.c,v 1.123 2001/01/10 17:41:50 roberto Exp roberto $
+** $Id: lparser.c,v 1.124 2001/01/15 16:13:24 roberto Exp roberto $
 ** LL(1) Parser and code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -65,7 +65,7 @@ static void next (LexState *ls) {
 
 
 static void lookahead (LexState *ls) {
-  LUA_ASSERT(ls->lookahead.token == TK_EOS, "two look-aheads");
+  lua_assert(ls->lookahead.token == TK_EOS);
   ls->lookahead.token = luaX_lex(ls, &ls->lookahead.seminfo);
 }
 
@@ -285,7 +285,7 @@ static void enterbreak (FuncState *fs, Breaklabel *bl) {
 
 static void leavebreak (FuncState *fs, Breaklabel *bl) {
   fs->bl = bl->previous;
-  LUA_ASSERT(bl->stacklevel == fs->stacklevel, "wrong levels");
+  lua_assert(bl->stacklevel == fs->stacklevel);
   luaK_patchlist(fs, bl->breaklist, luaK_getlabel(fs));
 }
 
@@ -352,7 +352,7 @@ static void close_func (LexState *ls) {
   f->lineinfo[fs->nlineinfo++] = MAX_INT;  /* end flag */
   f->sizelineinfo = fs->nlineinfo;
   ls->fs = fs->prev;
-  LUA_ASSERT(fs->bl == NULL, "wrong list end");
+  lua_assert(fs->bl == NULL);
 }
 
 
@@ -365,8 +365,8 @@ Proto *luaY_parser (lua_State *L, ZIO *z) {
   chunk(&lexstate);
   check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected");
   close_func(&lexstate);
-  LUA_ASSERT(funcstate.prev == NULL, "wrong list end");
-  LUA_ASSERT(funcstate.nupvalues == 0, "no upvalues in main");
+  lua_assert(funcstate.prev == NULL);
+  lua_assert(funcstate.nupvalues == 0);
   return funcstate.f;
 }
 
@@ -1130,8 +1130,7 @@ static void chunk (LexState *ls) {
   while (!islast && !block_follow(ls->t.token)) {
     islast = stat(ls);
     optional(ls, ';');
-    LUA_ASSERT(ls->fs->stacklevel == ls->fs->nactloc,
-               "stack size != # local vars");
+    lua_assert(ls->fs->stacklevel == ls->fs->nactloc);
   }
 }
 

+ 41 - 36
lstate.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.c,v 1.49 2000/12/26 18:46:09 roberto Exp roberto $
+** $Id: lstate.c,v 1.50 2000/12/28 12:55:41 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -47,6 +47,24 @@ static void f_luaopen (lua_State *L, void *ud) {
     stacksize = DEFAULT_STACK_SIZE;
   else
     stacksize += LUA_MINSTACK;
+  L->G = luaM_new(L, global_State);
+  G(L)->strt.size = G(L)->udt.size = 0;
+  G(L)->strt.nuse = G(L)->udt.nuse = 0;
+  G(L)->strt.hash = G(L)->udt.hash = NULL;
+  G(L)->Mbuffer = NULL;
+  G(L)->Mbuffsize = 0;
+  G(L)->rootproto = NULL;
+  G(L)->rootcl = NULL;
+  G(L)->roottable = NULL;
+  G(L)->TMtable = NULL;
+  G(L)->sizeTM = 0;
+  G(L)->ntag = 0;
+  G(L)->refArray = NULL;
+  G(L)->nref = 0;
+  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 */
   L->gt = luaH_new(L, 10);  /* table of globals */
   luaD_init(L, stacksize);
   luaS_init(L);
@@ -58,61 +76,48 @@ static void f_luaopen (lua_State *L, void *ud) {
 #ifdef LUA_DEBUG
   luaB_opentests(L);
   if (lua_state == NULL) lua_state = L;  /* keep first state to be opened */
-  LUA_ASSERT(lua_gettop(L) == 0, "wrong API stack");
+  lua_assert(lua_gettop(L) == 0);
 #endif
 }
 
 
 LUA_API lua_State *lua_open (int stacksize) {
-  lua_State *L = luaM_new(NULL, lua_State);
+  lua_State *L;
+  L = luaM_new(NULL, lua_State);
   if (L == NULL) return NULL;  /* memory allocation error */
+  L->G = NULL;
   L->stack = NULL;
   L->stacksize = 0;
-  L->strt.size = L->udt.size = 0;
-  L->strt.nuse = L->udt.nuse = 0;
-  L->strt.hash = L->udt.hash = NULL;
-  L->Mbuffer = NULL;
-  L->Mbuffsize = 0;
-  L->rootproto = NULL;
-  L->rootcl = NULL;
-  L->roottable = NULL;
-  L->TMtable = NULL;
-  L->sizeTM = 0;
-  L->ntag = 0;
-  L->refArray = NULL;
-  L->nref = 0;
-  L->sizeref = 0;
-  L->refFree = NONEXT;
-  L->nblocks = sizeof(lua_State);
-  L->GCthreshold = MAX_INT;  /* to avoid GC during pre-definitions */
+  L->errorJmp = NULL;
   L->callhook = NULL;
   L->linehook = NULL;
   L->allowhooks = 1;
-  L->errorJmp = NULL;
   if (luaD_runprotected(L, f_luaopen, &stacksize) != 0) {
     /* memory allocation error: free partial state */
     lua_close(L);
     return NULL;
   }
-  L->GCthreshold = 2*L->nblocks;
+  G(L)->GCthreshold = 2*G(L)->nblocks;
   return L;
 }
 
 
 LUA_API void lua_close (lua_State *L) {
-  LUA_ASSERT(L != lua_state || lua_gettop(L) == 0, "garbage in C stack");
-  luaC_collect(L, 1);  /* collect all elements */
-  LUA_ASSERT(L->rootproto == NULL, "list should be empty");
-  LUA_ASSERT(L->rootcl == NULL, "list should be empty");
-  LUA_ASSERT(L->roottable == NULL, "list should be empty");
-  luaS_freeall(L);
-  luaM_freearray(L, L->stack, L->stacksize, TObject);
-  luaM_freearray(L, L->TMtable, L->sizeTM, struct TM);
-  luaM_freearray(L, L->refArray, L->sizeref, struct Ref);
-  luaM_freearray(L, L->Mbuffer, L->Mbuffsize, char);
-  LUA_ASSERT(L->nblocks == sizeof(lua_State), "wrong count for nblocks");
-  luaM_freelem(L, L, lua_State);
-  LUA_ASSERT(L != lua_state || memdebug_numblocks == 0, "memory leak!");
-  LUA_ASSERT(L != lua_state || memdebug_total == 0,"memory leak!");
+  lua_assert(L != lua_state || lua_gettop(L) == 0);
+  if (G(L)) {  /* close global state */
+    luaC_collect(L, 1);  /* collect all elements */
+    lua_assert(G(L)->rootproto == NULL);
+    lua_assert(G(L)->rootcl == NULL);
+    lua_assert(G(L)->roottable == NULL);
+    luaS_freeall(L);
+    luaM_freearray(L, G(L)->TMtable, G(L)->sizeTM, struct TM);
+    luaM_freearray(L, G(L)->refArray, G(L)->sizeref, struct Ref);
+    luaM_freearray(L, G(L)->Mbuffer, G(L)->Mbuffsize, char);
+    luaM_freelem(NULL, L->G, global_State);
+  }
+  luaM_freearray(NULL, L->stack, L->stacksize, TObject);
+  luaM_freelem(NULL, L, lua_State);
+  lua_assert(L != lua_state || memdebug_numblocks == 0);
+  lua_assert(L != lua_state || memdebug_total == 0);
 }
 

+ 23 - 12
lstate.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.h,v 1.42 2000/11/24 17:39:56 roberto Exp roberto $
+** $Id: lstate.h,v 1.43 2000/12/26 18:46:09 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -42,24 +42,17 @@ typedef struct stringtable {
 } stringtable;
 
 
-
-struct lua_State {
-  /* thread-specific state */
-  StkId top;  /* first free slot in the stack */
-  StkId stack;  /* stack base */
-  StkId stack_last;  /* last free slot in the stack */
-  int stacksize;
-  StkId Cbase;  /* base for current C function */
-  struct lua_longjmp *errorJmp;  /* current error recover point */
+/*
+** "global state", shared by all threads of this state
+*/
+typedef struct global_State {
   char *Mbuffer;  /* global buffer */
   size_t Mbuffsize;  /* size of Mbuffer */
-  /* global state */
   Proto *rootproto;  /* list of all prototypes */
   Closure *rootcl;  /* list of all closures */
   Hash *roottable;  /* list of all tables */
   stringtable strt;  /* hash table for strings */
   stringtable udt;   /* hash table for udata */
-  Hash *gt;  /* table for globals */
   struct TM *TMtable;  /* table for tag methods */
   int sizeTM;  /* size of TMtable */
   int ntag;  /* number of tags in TMtable */
@@ -69,11 +62,29 @@ struct lua_State {
   int refFree;  /* list of free positions in refArray */
   mem_int GCthreshold;
   mem_int nblocks;  /* number of `bytes' currently allocated */
+} global_State;
+
+
+/*
+** "per thread" state
+*/
+struct lua_State {
+  StkId top;  /* first free slot in the stack */
+  StkId stack;  /* stack base */
+  StkId stack_last;  /* last free slot in the stack */
+  int stacksize;
+  StkId Cbase;  /* base for current C function */
+  struct lua_longjmp *errorJmp;  /* current error recover point */
+  Hash *gt;  /* table for globals */
   lua_Hook callhook;
   lua_Hook linehook;
   int allowhooks;
+  global_State *G;
 };
 
 
+#define G(L)	(L->G)
+
+
 #endif
 

+ 14 - 15
lstring.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lstring.c,v 1.49 2001/01/10 17:41:50 roberto Exp roberto $
+** $Id: lstring.c,v 1.50 2001/01/11 18:59:20 roberto Exp roberto $
 ** String table (keeps all strings handled by Lua)
 ** See Copyright Notice in lua.h
 */
@@ -19,16 +19,16 @@
 
 
 void luaS_init (lua_State *L) {
-  luaS_resize(L, &L->strt, MINPOWER2);
-  luaS_resize(L, &L->udt, MINPOWER2);
+  luaS_resize(L, &G(L)->strt, MINPOWER2);
+  luaS_resize(L, &G(L)->udt, MINPOWER2);
 }
 
 
 void luaS_freeall (lua_State *L) {
-  LUA_ASSERT(L->strt.nuse==0, "non-empty string table");
-  luaM_freearray(L, L->strt.hash, L->strt.size, TString *);
-  LUA_ASSERT(L->udt.nuse==0, "non-empty udata table");
-  luaM_freearray(L, L->udt.hash, L->udt.size, TString *);
+  lua_assert(G(L)->strt.nuse==0);
+  luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *);
+  lua_assert(G(L)->udt.nuse==0);
+  luaM_freearray(L, G(L)->udt.hash, G(L)->udt.size, TString *);
 }
 
 
@@ -41,10 +41,9 @@ void luaS_resize (lua_State *L, stringtable *tb, int newsize) {
     TString *p = tb->hash[i];
     while (p) {  /* for each node in the list */
       TString *next = p->nexthash;  /* save next */
-      luint32 h = (tb == &L->strt) ? p->u.s.hash : IntPoint(p->u.d.value);
+      luint32 h = (tb == &G(L)->strt) ? p->u.s.hash : IntPoint(p->u.d.value);
       int h1 = lmod(h, newsize);  /* new position */
-      LUA_ASSERT((int)(h%newsize) == lmod(h, newsize),
-                    "a&(x-1) == a%x, for x power of 2");
+      lua_assert((int)(h%newsize) == lmod(h, newsize));
       p->nexthash = newhash[h1];  /* chain it in new position */
       newhash[h1] = p;
       p = next;
@@ -73,7 +72,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
   size_t l1;
   for (l1=l; l1>=step; l1-=step)  /* compute hash */
     h = h ^ ((h<<5)+(h>>2)+(unsigned char)str[l1-1]);
-  for (ts = L->strt.hash[lmod(h, L->strt.size)]; ts; ts = ts->nexthash) {
+  for (ts = G(L)->strt.hash[lmod(h, G(L)->strt.size)]; ts; ts = ts->nexthash) {
     if (ts->len == l && (memcmp(str, ts->str, l) == 0))
       return ts;
   }
@@ -86,7 +85,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
   ts->u.s.constindex = 0;
   memcpy(ts->str, str, l);
   ts->str[l] = 0;  /* ending 0 */
-  newentry(L, &L->strt, ts, lmod(h, L->strt.size));  /* insert it on table */
+  newentry(L, &G(L)->strt, ts, lmod(h, G(L)->strt.size));  /* insert it */
   return ts;
 }
 
@@ -100,15 +99,15 @@ TString *luaS_newudata (lua_State *L, size_t s, void *udata) {
   ts->u.d.tag = 0;
   ts->u.d.value = (udata == NULL) ? uts+1 : udata;
   /* insert it on table */
-  newentry(L, &L->udt, ts, lmod(IntPoint(ts->u.d.value), L->udt.size));
+  newentry(L, &G(L)->udt, ts, lmod(IntPoint(ts->u.d.value), G(L)->udt.size));
   return ts;
 }
 
 
 TString *luaS_createudata (lua_State *L, void *udata, int tag) {
-  int h1 = lmod(IntPoint(udata), L->udt.size);
+  int h1 = lmod(IntPoint(udata), G(L)->udt.size);
   TString *ts;
-  for (ts = L->udt.hash[h1]; ts; ts = ts->nexthash) {
+  for (ts = G(L)->udt.hash[h1]; ts; ts = ts->nexthash) {
     if (udata == ts->u.d.value && (tag == ts->u.d.tag || tag == LUA_ANYTAG))
       return ts;
   }

+ 5 - 5
ltable.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltable.c,v 1.63 2001/01/10 18:56:11 roberto Exp roberto $
+** $Id: ltable.c,v 1.64 2001/01/18 15:59:09 roberto Exp roberto $
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 */
@@ -144,7 +144,7 @@ void luaH_remove (Hash *t, TObject *key) {
       n += t->size;
     }
     setnvalue(key, n);
-    LUA_ASSERT(luaH_mainposition(t, key) == mp, "cannot change hash");
+    lua_assert(luaH_mainposition(t, key) == mp);
   }
 }
 
@@ -167,8 +167,8 @@ static void setnodevector (lua_State *L, Hash *t, luint32 size) {
 Hash *luaH_new (lua_State *L, int size) {
   Hash *t = luaM_new(L, Hash);
   t->htag = TagDefault;
-  t->next = L->roottable;
-  L->roottable = t;
+  t->next = G(L)->roottable;
+  G(L)->roottable = t;
   t->mark = t;
   t->size = 0;
   t->node = NULL;
@@ -201,7 +201,7 @@ static void rehash (lua_State *L, Hash *t) {
   Node *nold = t->node;
   int nelems = numuse(t);
   int i;
-  LUA_ASSERT(nelems<=oldsize, "wrong count");
+  lua_assert(nelems<=oldsize);
   if (nelems >= oldsize-oldsize/4)  /* using more than 3/4? */
     setnodevector(L, t, (luint32)oldsize*2);
   else if (nelems <= oldsize/4 &&  /* less than 1/4? */

+ 3 - 2
ltests.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltests.c,v 1.56 2001/01/15 16:13:24 roberto Exp roberto $
+** $Id: ltests.c,v 1.57 2001/01/18 15:59:09 roberto Exp roberto $
 ** Internal Module for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 */
@@ -215,7 +215,8 @@ static int table_query (lua_State *L) {
 
 
 static int string_query (lua_State *L) {
-  stringtable *tb = (*luaL_check_string(L, 1) == 's') ? &L->strt : &L->udt;
+  stringtable *tb = (*luaL_check_string(L, 1) == 's') ? &G(L)->strt :
+                                                        &G(L)->udt;
   int s = luaL_opt_int(L, 2, 0) - 1;
   if (s==-1) {
     lua_pushnumber(L ,tb->nuse);

+ 17 - 17
ltm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltm.c,v 1.59 2000/12/28 12:55:41 roberto Exp roberto $
+** $Id: ltm.c,v 1.60 2001/01/18 15:59:09 roberto Exp roberto $
 ** Tag methods
 ** See Copyright Notice in lua.h
 */
@@ -68,36 +68,36 @@ int luaT_validevent (int t, int e) {  /* ORDER LUA_T */
 static void init_entry (lua_State *L, int tag) {
   int i;
   for (i=0; i<TM_N; i++)
-    luaT_gettm(L, tag, i) = NULL;
-  L->TMtable[tag].collected = NULL;
+    luaT_gettm(G(L), tag, i) = NULL;
+  G(L)->TMtable[tag].collected = NULL;
 }
 
 
 void luaT_init (lua_State *L) {
   int t;
-  L->TMtable = luaM_newvector(L, NUM_TAGS+2, struct TM);
-  L->sizeTM = NUM_TAGS+2;
-  L->ntag = NUM_TAGS;
-  for (t=0; t<L->ntag; t++)
+  G(L)->TMtable = luaM_newvector(L, NUM_TAGS+2, struct TM);
+  G(L)->sizeTM = NUM_TAGS+2;
+  G(L)->ntag = NUM_TAGS;
+  for (t=0; t<G(L)->ntag; t++)
     init_entry(L, t);
 }
 
 
 LUA_API int lua_newtag (lua_State *L) {
-  luaM_growvector(L, L->TMtable, L->ntag, L->sizeTM, struct TM,
+  luaM_growvector(L, G(L)->TMtable, G(L)->ntag, G(L)->sizeTM, struct TM,
                   MAX_INT, "tag table overflow");
-  init_entry(L, L->ntag);
-  return L->ntag++;
+  init_entry(L, G(L)->ntag);
+  return G(L)->ntag++;
 }
 
 
 static void checktag (lua_State *L, int tag) {
-  if (!(0 <= tag && tag < L->ntag))
+  if (!(0 <= tag && tag < G(L)->ntag))
     luaO_verror(L, "%d is not a valid tag", tag);
 }
 
 void luaT_realtag (lua_State *L, int tag) {
-  if (!validtag(tag))
+  if (!validtag(G(L), tag))
     luaO_verror(L, "tag %d was not created by `newtag'", tag);
 }
 
@@ -108,7 +108,7 @@ LUA_API int lua_copytagmethods (lua_State *L, int tagto, int tagfrom) {
   checktag(L, tagfrom);
   for (e=0; e<TM_N; e++) {
     if (luaT_validevent(tagto, e))
-      luaT_gettm(L, tagto, e) = luaT_gettm(L, tagfrom, e);
+      luaT_gettm(G(L), tagto, e) = luaT_gettm(G(L), tagfrom, e);
   }
   return tagto;
 }
@@ -128,8 +128,8 @@ LUA_API void lua_gettagmethod (lua_State *L, int t, const char *event) {
   int e;
   e = luaI_checkevent(L, event, t);
   checktag(L, t);
-  if (luaT_validevent(t, e) && luaT_gettm(L, t, e)) {
-    setclvalue(L->top, luaT_gettm(L, t, e));
+  if (luaT_validevent(t, e) && luaT_gettm(G(L), t, e)) {
+    setclvalue(L->top, luaT_gettm(G(L), t, e));
   }
   else
     setnilvalue(L->top);
@@ -147,10 +147,10 @@ LUA_API void lua_settagmethod (lua_State *L, int t, const char *event) {
                    " with default tag" : "");
   switch (ttype(L->top - 1)) {
     case LUA_TNIL:
-      luaT_gettm(L, t, e) = NULL;
+      luaT_gettm(G(L), t, e) = NULL;
       break;
     case LUA_TFUNCTION:
-      luaT_gettm(L, t, e) = clvalue(L->top - 1);
+      luaT_gettm(G(L), t, e) = clvalue(L->top - 1);
       break;
     default:
       lua_error(L, "tag method must be a function (or nil)");

+ 4 - 4
ltm.h

@@ -1,5 +1,5 @@
 /*
-** $Id: ltm.h,v 1.18 2000/10/05 13:00:17 roberto Exp roberto $
+** $Id: ltm.h,v 1.19 2000/12/26 18:46:09 roberto Exp roberto $
 ** Tag methods
 ** See Copyright Notice in lua.h
 */
@@ -41,11 +41,11 @@ struct TM {
 };
 
 
-#define luaT_gettm(L,tag,event) (L->TMtable[tag].method[event])
-#define luaT_gettmbyObj(L,o,e)  (luaT_gettm((L),luaT_tag(o),(e)))
+#define luaT_gettm(G,tag,event) (G->TMtable[tag].method[event])
+#define luaT_gettmbyObj(G,o,e)  (luaT_gettm((G),luaT_tag(o),(e)))
 
 
-#define validtag(t) (NUM_TAGS <= (t) && (t) < L->ntag)
+#define validtag(G,t) (NUM_TAGS <= (t) && (t) < G->ntag)
 
 extern const char *const luaT_eventname[];
 

+ 15 - 15
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 1.153 2001/01/15 16:13:24 roberto Exp roberto $
+** $Id: lvm.c,v 1.154 2001/01/18 15:59:09 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -118,16 +118,16 @@ const TObject *luaV_gettable (lua_State *L, StkId t) {
   int tg;
   if (ttype(t) == LUA_TTABLE &&  /* `t' is a table? */
       ((tg = hvalue(t)->htag) == LUA_TTABLE ||  /* with default tag? */
-        luaT_gettm(L, tg, TM_GETTABLE) == NULL)) { /* or no TM? */
+        luaT_gettm(G(L), tg, TM_GETTABLE) == NULL)) { /* or no TM? */
     /* do a primitive get */
     const TObject *h = luaH_get(hvalue(t), L->top-1);
     /* result is no nil or there is no `index' tag method? */
-    if (ttype(h) != LUA_TNIL || ((tm=luaT_gettm(L, tg, TM_INDEX)) == NULL))
+    if (ttype(h) != LUA_TNIL || ((tm=luaT_gettm(G(L), tg, TM_INDEX)) == NULL))
       return h;  /* return result */
     /* else call `index' tag method */
   }
   else {  /* try a `gettable' tag method */
-    tm = luaT_gettmbyObj(L, t, TM_GETTABLE);
+    tm = luaT_gettmbyObj(G(L), t, TM_GETTABLE);
   }
   if (tm != NULL) {  /* is there a tag method? */
     luaD_checkstack(L, 2);
@@ -152,11 +152,11 @@ void luaV_settable (lua_State *L, StkId t, StkId key) {
   int tg;
   if (ttype(t) == LUA_TTABLE &&  /* `t' is a table? */
       ((tg = hvalue(t)->htag) == LUA_TTABLE ||  /* with default tag? */
-        luaT_gettm(L, tg, TM_SETTABLE) == NULL)) { /* or no TM? */
+        luaT_gettm(G(L), tg, TM_SETTABLE) == NULL)) { /* or no TM? */
     setobj(luaH_set(L, hvalue(t), key), L->top-1);  /* do a primitive set */
   }
   else {  /* try a `settable' tag method */
-    Closure *tm = luaT_gettmbyObj(L, t, TM_SETTABLE);
+    Closure *tm = luaT_gettmbyObj(G(L), t, TM_SETTABLE);
     if (tm != NULL) {
       luaD_checkstack(L, 3);
       setobj(L->top+2, L->top-1);
@@ -174,7 +174,7 @@ void luaV_settable (lua_State *L, StkId t, StkId key) {
 
 const TObject *luaV_getglobal (lua_State *L, TString *s) {
   const TObject *value = luaH_getstr(L->gt, s);
-  Closure *tm = luaT_gettmbyObj(L, value, TM_GETGLOBAL);
+  Closure *tm = luaT_gettmbyObj(G(L), value, TM_GETGLOBAL);
   if (tm == NULL)  /* is there a tag method? */
     return value;  /* default behavior */
   else {  /* tag method */
@@ -191,7 +191,7 @@ const TObject *luaV_getglobal (lua_State *L, TString *s) {
 
 void luaV_setglobal (lua_State *L, TString *s) {
   TObject *oldvalue = luaH_setstr(L, L->gt, s);
-  Closure *tm = luaT_gettmbyObj(L, oldvalue, TM_SETGLOBAL);
+  Closure *tm = luaT_gettmbyObj(G(L), oldvalue, TM_SETGLOBAL);
   if (tm == NULL) {  /* no tag methods? */
     setobj(oldvalue, L->top - 1);  /* raw set */
   }
@@ -209,12 +209,12 @@ void luaV_setglobal (lua_State *L, TString *s) {
 
 static int call_binTM (lua_State *L, StkId top, TMS event) {
   /* try first operand */
-  Closure *tm = luaT_gettmbyObj(L, top-2, event);
+  Closure *tm = luaT_gettmbyObj(G(L), top-2, event);
   L->top = top;
   if (tm == NULL) {
-    tm = luaT_gettmbyObj(L, top-1, event);  /* try second operand */
+    tm = luaT_gettmbyObj(G(L), top-1, event);  /* try second operand */
     if (tm == NULL) {
-      tm = luaT_gettm(L, 0, event);  /* try a `global' method */
+      tm = luaT_gettm(G(L), 0, event);  /* try a `global' method */
       if (tm == NULL)
         return 0;  /* error */
     }
@@ -369,7 +369,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
       }
       case OP_PUSHNIL: {
         int n = GETARG_U(i);
-        LUA_ASSERT(n>0, "invalid argument");
+        lua_assert(n>0);
         do {
           setnilvalue(top++);
         } while (--n > 0);
@@ -620,8 +620,8 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
         break;
       }
       case OP_FORLOOP: {
-        LUA_ASSERT(ttype(top-1) == LUA_TNUMBER, "invalid step");
-        LUA_ASSERT(ttype(top-2) == LUA_TNUMBER, "invalid limit");
+        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");
         nvalue(top-3) += nvalue(top-1);  /* increment index */
@@ -651,7 +651,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
       }
       case OP_LFORLOOP: {
         Node *node;
-        LUA_ASSERT(ttype(top-3) == LUA_TTABLE, "invalid table");
+        lua_assert(ttype(top-3) == LUA_TTABLE);
         node = luaH_next(L, hvalue(top-3), top-2);
         if (node == NULL)  /* end loop? */
           top -= 3;  /* remove table, key, and value */