Browse Source

new implementation for globals: Global value is stored in TaggedString

Roberto Ierusalimschy 28 years ago
parent
commit
a580480b07
17 changed files with 251 additions and 288 deletions
  1. 11 11
      lapi.c
  2. 10 1
      lauxlib.c
  3. 2 1
      lauxlib.h
  4. 40 36
      lbuiltin.c
  5. 3 1
      ldo.c
  6. 21 10
      lgc.c
  7. 0 71
      lglobal.c
  8. 0 35
      lglobal.h
  9. 5 6
      llex.c
  10. 55 58
      lobject.h
  11. 65 19
      lstring.c
  12. 5 1
      lstring.h
  13. 2 2
      ltm.c
  14. 4 4
      lua.stx
  15. 10 11
      lvm.c
  16. 3 3
      lvm.h
  17. 15 18
      makefile

+ 11 - 11
lapi.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 1.1 1997/08/14 13:40:46 roberto Exp roberto $
+** $Id: lapi.c,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -13,7 +13,6 @@
 #include "ldo.h"
 #include "lfunc.h"
 #include "lgc.h"
-#include "lglobal.h"
 #include "lmem.h"
 #include "lobject.h"
 #include "lstring.h"
@@ -182,14 +181,15 @@ lua_Object lua_createtable (void)
 lua_Object lua_getglobal (char *name)
 {
   luaD_checkstack(2);  /* may need that to call T.M. */
-  luaV_getglobal(luaG_findsymbolbyname(name));
+  luaV_getglobal(luaS_new(name));
   return put_luaObjectonTop();
 }
 
 
 lua_Object lua_rawgetglobal (char *name)
 {
-  return put_luaObject(&luaG_global[luaG_findsymbolbyname(name)].object);
+  TaggedString *ts = luaS_new(name);
+  return put_luaObject(&ts->u.globalval);
 }
 
 
@@ -197,15 +197,15 @@ void lua_setglobal (char *name)
 {
   checkCparams(1);
   luaD_checkstack(2);  /* may need that to call T.M. */
-  luaV_setglobal(luaG_findsymbolbyname(name));
+  luaV_setglobal(luaS_new(name));
 }
 
 
 void lua_rawsetglobal (char *name)
 {
-  Word n = luaG_findsymbolbyname(name);
+  TaggedString *ts = luaS_new(name);
   checkCparams(1);
-  s_object(n) = *(--luaD_stack.top);
+  luaS_rawsetglobal(ts, --luaD_stack.top);
 }
 
 
@@ -268,7 +268,7 @@ void *lua_getuserdata (lua_Object object)
 {
   if (object == LUA_NOOBJECT || ttype(Address(object)) != LUA_T_USERDATA)
     return NULL;
-  else return tsvalue(Address(object))->u.v;
+  else return tsvalue(Address(object))->u.d.v;
 }
 
 lua_CFunction lua_getcfunction (lua_Object object)
@@ -352,7 +352,7 @@ int lua_tag (lua_Object lo)
     TObject *o = Address(lo);
     lua_Type t = ttype(o);
     if (t == LUA_T_USERDATA)
-      return o->value.ts->tag;
+      return o->value.ts->u.d.tag;
     else if (t == LUA_T_ARRAY)
       return o->value.a->htag;
     else return t;
@@ -369,7 +369,7 @@ void lua_settag (int tag)
       (luaD_stack.top-1)->value.a->htag = tag;
       break;
     case LUA_T_USERDATA:
-      (luaD_stack.top-1)->value.ts->tag = tag;
+      (luaD_stack.top-1)->value.ts->u.d.tag = tag;
       break;
     default:
       luaL_verror("cannot change the tag of a %s",
@@ -483,7 +483,7 @@ char *lua_getobjname (lua_Object o, char **name)
   functofind = Address(o);
   if ((*name = luaT_travtagmethods(checkfunc)) != NULL)
     return "tag-method";
-  else if ((*name = luaG_travsymbol(checkfunc)) != NULL)
+  else if ((*name = luaS_travsymbol(checkfunc)) != NULL)
     return "global";
   else return "";
 }

+ 10 - 1
lauxlib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: $
+** $Id: lauxlib.c,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $
 ** Auxiliar functions for building Lua libraries
 ** See Copyright Notice in lua.h
 */
@@ -57,6 +57,13 @@ double luaL_opt_number (int numArg, double def)
                               luaL_check_number(numArg);
 }
 
+lua_Object luaL_nonnullarg (int numArg)
+{
+  lua_Object o = lua_getparam(numArg);
+  luaL_arg_check(o != LUA_NOOBJECT, numArg, "value expected");
+  return o;
+}
+
 void luaL_openlib (struct luaL_reg *l, int n)
 {
   int i;
@@ -74,3 +81,5 @@ void luaL_verror (char *fmt, ...)
   va_end(argp);
   lua_error(buff);
 }
+
+

+ 2 - 1
lauxlib.h

@@ -1,5 +1,5 @@
 /*
-** $Id: $
+** $Id: lauxlib.h,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $
 ** Auxiliar functions for building Lua libraries
 ** See Copyright Notice in lua.h
 */
@@ -23,6 +23,7 @@ char *luaL_check_string (int numArg);
 char *luaL_opt_string (int numArg, char *def);
 double luaL_check_number (int numArg);
 double luaL_opt_number (int numArg, double def);
+lua_Object luaL_nonnullarg (int numArg);
 void luaL_verror (char *fmt, ...);
 
 

+ 40 - 36
lbuiltin.c

@@ -1,5 +1,5 @@
 /*
-** $Id: $
+** $Id: lbuiltin.c,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $
 ** Built-in functions
 ** See Copyright Notice in lua.h
 */
@@ -10,7 +10,6 @@
 #include "lapi.h"
 #include "lauxlib.h"
 #include "lbuiltin.h"
-#include "lglobal.h"
 #include "lmem.h"
 #include "lstring.h"
 #include "ltable.h"
@@ -18,13 +17,25 @@
 #include "lua.h"
 
 
+
 static void nextvar (void)
 {
-  int i = luaG_nextvar(lua_isnil(lua_getparam(1)) ? 0 :
-                             luaG_findsymbolbyname(luaL_check_string(1))+1);
-  if (i >= 0) {
-    lua_pushstring(luaG_global[i].varname->str);
-    luaA_pushobject(&s_object(i));
+  lua_Object v = luaL_nonnullarg(1);
+  TaggedString *g;
+  if (lua_isnil(v))
+    g = (TaggedString *)luaS_root.next;
+  else {
+    TObject *o = luaA_Address(v);
+    luaL_arg_check(ttype(o) == LUA_T_STRING, 1, "variable name expected");
+    g = tsvalue(o);
+    luaL_arg_check((GCnode *)g != g->head.next, 1, "variable name expected");
+    g = (TaggedString *)g->head.next;
+  }
+  while (g && g->u.globalval.ttype == LUA_T_NIL)
+    g = (TaggedString *)g->head.next;
+  if (g) {
+    lua_pushstring(g->str);
+    luaA_pushobject(&g->u.globalval);
   }
 }
 
@@ -32,10 +43,9 @@ static void nextvar (void)
 static void next (void)
 {
   lua_Object o = lua_getparam(1);
-  lua_Object r = lua_getparam(2);
+  lua_Object r = luaL_nonnullarg(2);
   Node *n;
   luaL_arg_check(lua_istable(o), 1, "table expected");
-  luaL_arg_check(r != LUA_NOOBJECT, 2, "value expected");
   n = luaH_next(luaA_Address(o), luaA_Address(r));
   if (n) {
     luaA_pushobject(&n->ref);
@@ -90,7 +100,7 @@ static char *to_string (lua_Object obj)
       return buff;
     }
     case LUA_T_USERDATA: {
-      sprintf(buff, "userdata: %p", o->value.ts->u.v);
+      sprintf(buff, "userdata: %p", o->value.ts->u.d.v);
       return buff;
     }
     case LUA_T_NIL:
@@ -116,8 +126,7 @@ static void luaI_print (void)
 
 static void luaI_type (void)
 {
-  lua_Object o = lua_getparam(1);
-  luaL_arg_check(o != LUA_NOOBJECT, 1, "no argument");
+  lua_Object o = luaL_nonnullarg(1);
   lua_pushstring(luaO_typenames[-ttype(luaA_Address(o))]);
   lua_pushnumber(lua_tag(o));
 }
@@ -149,8 +158,7 @@ static void luaI_assert (void)
 
 static void setglobal (void)
 {
-  lua_Object value = lua_getparam(2);
-  luaL_arg_check(value != LUA_NOOBJECT, 2, NULL);
+  lua_Object value = luaL_nonnullarg(2);
   lua_pushobject(value);
   lua_setglobal(luaL_check_string(1));
   lua_pushobject(value);  /* return given value */
@@ -158,8 +166,7 @@ static void setglobal (void)
 
 static void rawsetglobal (void)
 {
-  lua_Object value = lua_getparam(2);
-  luaL_arg_check(value != LUA_NOOBJECT, 2, NULL);
+  lua_Object value = luaL_nonnullarg(2);
   lua_pushobject(value);
   lua_rawsetglobal(luaL_check_string(1));
   lua_pushobject(value);  /* return given value */
@@ -233,10 +240,8 @@ static void newtag (void)
 
 static void rawgettable (void)
 {
-  lua_Object t = lua_getparam(1);
-  lua_Object i = lua_getparam(2);
-  luaL_arg_check(t != LUA_NOOBJECT, 1, NULL);
-  luaL_arg_check(i != LUA_NOOBJECT, 2, NULL);
+  lua_Object t = luaL_nonnullarg(1);
+  lua_Object i = luaL_nonnullarg(2);
   lua_pushobject(t);
   lua_pushobject(i);
   lua_pushobject(lua_rawgettable());
@@ -245,11 +250,9 @@ static void rawgettable (void)
 
 static void rawsettable (void)
 {
-  lua_Object t = lua_getparam(1);
-  lua_Object i = lua_getparam(2);
-  lua_Object v = lua_getparam(3);
-  luaL_arg_check(t != LUA_NOOBJECT && i != LUA_NOOBJECT && v != LUA_NOOBJECT,
-                 0, NULL);
+  lua_Object t = luaL_nonnullarg(1);
+  lua_Object i = luaL_nonnullarg(2);
+  lua_Object v = luaL_nonnullarg(3);
   lua_pushobject(t);
   lua_pushobject(i);
   lua_pushobject(v);
@@ -259,8 +262,7 @@ static void rawsettable (void)
 
 static void settagmethod (void)
 {
-  lua_Object nf = lua_getparam(3);
-  luaL_arg_check(nf != LUA_NOOBJECT, 3, "value expected");
+  lua_Object nf = luaL_nonnullarg(3);
   lua_pushobject(nf);
   lua_pushobject(lua_settagmethod((int)luaL_check_number(1),
                                   luaL_check_string(2)));
@@ -276,8 +278,7 @@ static void gettagmethod (void)
 
 static void seterrormethod (void)
 {
-  lua_Object nf = lua_getparam(1);
-  luaL_arg_check(nf != LUA_NOOBJECT, 1, "value expected");
+  lua_Object nf = luaL_nonnullarg(1);
   lua_pushobject(nf);
   lua_pushobject(lua_seterrormethod());
 }
@@ -387,18 +388,21 @@ static struct luaL_reg int_funcs[] = {
 void luaB_predefine (void)
 {
   int i;
-  Word n;
+  TaggedString *ts;
+  TObject o;
   /* pre-register mem error messages, to avoid loop when error arises */
   luaS_newfixedstring(tableEM);
   luaS_newfixedstring(memEM);
+  o.ttype = LUA_T_CFUNCTION;
   for (i=0; i<INTFUNCSIZE; i++) {
-    n = luaG_findsymbolbyname(int_funcs[i].name);
-    s_ttype(n) = LUA_T_CFUNCTION;
-    fvalue(&s_object(n)) = int_funcs[i].func;
+    ts = luaS_new(int_funcs[i].name);
+    fvalue(&o) = int_funcs[i].func;
+    luaS_rawsetglobal(ts, &o);
   }
-  n = luaG_findsymbolbyname("_VERSION");
-  s_ttype(n) = LUA_T_STRING;
-  tsvalue(&s_object(n)) = luaS_new(LUA_VERSION);
+  ts = luaS_new("_VERSION");
+  ttype(&o) = LUA_T_STRING;
+  tsvalue(&o) = luaS_new(LUA_VERSION);
+  luaS_rawsetglobal(ts, &o);
 }
 
 

+ 3 - 1
ldo.c

@@ -1,5 +1,5 @@
 /*
-** $Id: $
+** $Id: ldo.c,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -9,6 +9,7 @@
 #include <stdio.h>
 #include <string.h>
 
+#include "lbuiltin.h"
 #include "ldo.h"
 #include "lgc.h"
 #include "lmem.h"
@@ -50,6 +51,7 @@ static void initstack (int n)
   luaD_stack.last = luaD_stack.stack+(maxstack-1);
   luaD_stack.top = luaD_stack.stack;
   *(luaD_stack.top++) = initial_stack;
+  luaB_predefine();
 }
 
 

+ 21 - 10
lgc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: $
+** $Id: lgc.c,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -8,7 +8,6 @@
 #include "ldo.h"
 #include "lfunc.h"
 #include "lgc.h"
-#include "lglobal.h"
 #include "lmem.h"
 #include "lobject.h"
 #include "lstring.h"
@@ -91,7 +90,7 @@ static int ismarked (TObject *o)
 {
   switch (o->ttype) {
     case LUA_T_STRING: case LUA_T_USERDATA:
-      return o->value.ts->marked;
+      return o->value.ts->head.marked;
     case LUA_T_FUNCTION:
       return o->value.cl->head.marked;
     case LUA_T_PROTO:
@@ -129,10 +128,11 @@ static void strcallIM (TaggedString *l)
 {
   TObject o;
   ttype(&o) = LUA_T_USERDATA;
-  for (; l; l=l->uu.next) {
-    tsvalue(&o) = l;
-    luaD_gcIM(&o);
-  }
+  for (; l; l=(TaggedString *)l->head.next)
+    if (l->constindex == -1) {  /* is userdata? */
+      tsvalue(&o) = l;
+      luaD_gcIM(&o);
+    }
 }
 
 
@@ -164,8 +164,8 @@ static GCnode *listcollect (GCnode **root)
 
 static void strmark (TaggedString *s)
 {
-  if (!s->marked)
-    s->marked = 1;
+  if (!s->head.marked)
+    s->head.marked = 1;
 }
 
 
@@ -215,6 +215,17 @@ static void hashmark (Hash *h)
 }
 
 
+static void globalmark (void)
+{
+  TaggedString *g;
+  for (g=(TaggedString *)luaS_root.next; g; g=(TaggedString *)g->head.next)
+    if (g->u.globalval.ttype != LUA_T_NIL) {
+      markobject(&g->u.globalval);
+      strmark(g);  /* cannot collect non nil global variables */
+    }
+}
+
+
 static int markobject (TObject *o)
 {
   switch (ttype(o)) {
@@ -253,7 +264,7 @@ long luaC_threshold = GARBAGE_BLOCK;
 static void markall (void)
 {
   luaD_travstack(markobject); /* mark stack objects */
-  luaG_travsymbol(markobject); /* mark symbol table objects */
+  globalmark();  /* mark global variable values and names */
   travlock(); /* mark locked objects */
   luaT_travtagmethods(markobject);  /* mark fallbacks */
 }

+ 0 - 71
lglobal.c

@@ -1,71 +0,0 @@
-/*
-** $Id: $
-** Global variables
-** See Copyright Notice in lua.h
-*/
-
-#include <stdlib.h>
-
-#include "lbuiltin.h"
-#include "lglobal.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lstring.h"
-
-
-Symbol *luaG_global = NULL;
-int luaG_nglobal = 0;
-static int maxglobal = 0;
-
-
-
-Word luaG_findsymbol (TaggedString *t)
-{
-  if (maxglobal == 0) {  /* first time? */
-    maxglobal = 50;
-    luaG_global = luaM_newvector(maxglobal, Symbol);
-    luaB_predefine();
-  }
-  if (t->u.s.varindex == NOT_USED) {
-    if (!t->marked) t->marked = 2;  /* avoid GC of global variable names */
-    if (luaG_nglobal >= maxglobal)
-      maxglobal = luaM_growvector(&luaG_global, maxglobal, Symbol,
-                             symbolEM, MAX_WORD);
-    t->u.s.varindex = luaG_nglobal;
-    luaG_global[luaG_nglobal].varname = t;
-    s_ttype(luaG_nglobal) = LUA_T_NIL;
-    luaG_nglobal++;
-  }
-  return t->u.s.varindex;
-}
-
-
-Word luaG_findsymbolbyname (char *name)
-{
-  return luaG_findsymbol(luaS_new(name));
-}
-
-
-int luaG_globaldefined (char *name)
-{
-  return s_ttype(luaG_findsymbolbyname(name)) != LUA_T_NIL;
-}
-
-
-int luaG_nextvar (Word next)
-{
-  while (next < luaG_nglobal && s_ttype(next) == LUA_T_NIL)
-    next++;
-  return (next < luaG_nglobal ? next : -1);
-}
-
-
-char *luaG_travsymbol (int (*fn)(TObject *))
-{
-  int i;
-  for (i=0; i<luaG_nglobal; i++)
-    if (fn(&s_object(i)))
-      return luaG_global[i].varname->str;
-  return NULL;
-}
-

+ 0 - 35
lglobal.h

@@ -1,35 +0,0 @@
-/*
-** $Id: $
-** Global variables
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lglobal_h
-#define lglobal_h
-
-
-#include "lobject.h"
-
-
-typedef struct {
- TObject object;
- TaggedString *varname;
-} Symbol;
-
-
-extern Symbol *luaG_global;  /* global variables */
-extern int luaG_nglobal;  /* number of global variable (for luac) */
-
-
-Word luaG_findsymbolbyname (char *name);
-Word luaG_findsymbol (TaggedString *t);
-int luaG_globaldefined (char *name);
-int luaG_nextvar (Word next);
-char *luaG_travsymbol (int (*fn)(TObject *));
-
-
-#define s_object(i)     (luaG_global[i].object)
-#define s_ttype(i)	(ttype(&s_object(i)))
-
-
-#endif

+ 5 - 6
llex.c

@@ -1,5 +1,5 @@
 /*
-** $Id: $
+** $Id: llex.c,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $
 ** Lexical Analizer
 ** See Copyright Notice in lua.h
 */
@@ -8,7 +8,6 @@
 #include <ctype.h>
 #include <string.h>
 
-#include "lglobal.h"
 #include "llex.h"
 #include "lmem.h"
 #include "lobject.h"
@@ -48,7 +47,7 @@ static void addReserved (void)
     firsttime = 0;
     for (i=0; i<(sizeof(reserved)/sizeof(reserved[0])); i++) {
       TaggedString *ts = luaS_new(reserved[i].name);
-      ts->marked = reserved[i].token;  /* reserved word  (always > 255) */
+      ts->head.marked = reserved[i].token;  /* reserved word  (always > 255) */
     }
   }
 }
@@ -120,7 +119,7 @@ static int checkcond (char *buff)
   int i = luaO_findstring(buff, opts);
   if (i >= 0) return i;
   else if (isalpha((unsigned char)buff[0]) || buff[0] == '_')
-    return luaG_globaldefined(buff);
+    return luaS_globaldefined(buff);
   else {
     luaY_syntaxerror("invalid $if condition", buff);
     return 0;  /* to avoid warnings */
@@ -451,8 +450,8 @@ int luaY_lex (void)
           } while (isalnum(current) || current == '_');
           save(0);
           ts = luaS_new(textbuff.text);
-          if (ts->marked > 255)
-            return ts->marked;  /* reserved word */
+          if (ts->head.marked > 255)
+            return ts->head.marked;  /* reserved word */
           luaY_lval.pTStr = ts;
           return NAME;
         }

+ 55 - 58
lobject.h

@@ -1,5 +1,5 @@
 /*
-** $Id: $
+** $Id: lobject.h,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $
 ** Type definitions for Lua objects
 ** See Copyright Notice in lua.h
 */
@@ -29,30 +29,43 @@ typedef unsigned short Word;  /* unsigned 16 bits */
 typedef unsigned int IntPoint; /* unsigned with same size as a pointer (for hashing) */
 
 
-
-
 /*
-** String headers for string table
+** Lua TYPES
+** WARNING: if you change the order of this enumeration,
+** grep "ORDER LUA_T"
 */
+typedef enum {
+  LUA_T_NIL      = -10,
+  LUA_T_NUMBER   = -9,
+  LUA_T_STRING   = -8,
+  LUA_T_ARRAY    = -7,  /* array==table */
+  LUA_T_PROTO    = -6,
+  LUA_T_FUNCTION = -5,
+  LUA_T_CFUNCTION= -4,
+  LUA_T_MARK     = -3,
+  LUA_T_CMARK    = -2,
+  LUA_T_LINE     = -1,
+  LUA_T_USERDATA = 0
+} lua_Type;
 
-#define NOT_USED  0xFFFE
+#define NUM_TYPES 11
+
+
+typedef union {
+  lua_CFunction f;  /* LUA_T_CFUNCTION, LUA_T_CMARK */
+  real n;  /* LUA_T_NUMBER */
+  struct TaggedString *ts;  /* LUA_T_STRING, LUA_T_USERDATA */
+  struct TProtoFunc *tf;  /* LUA_T_PROTO */
+  struct Closure *cl;  /* LUA_T_FUNCTION, LUA_T_MARK */
+  struct Hash *a;  /* LUA_T_ARRAY */
+  int i;  /* LUA_T_LINE */
+} Value;
 
-typedef struct TaggedString {
-  int tag;  /* if != LUA_T_STRING, this is a userdata */
-  union {
-    unsigned long hash;
-    struct TaggedString *next;
-  } uu;
-  union {
-    struct {
-      Word varindex;  /* != NOT_USED  if this is a symbol */
-      Word constindex;  /* hint to reuse constant indexes */
-    } s;
-    void *v;  /* if this is a userdata, here is its value */
-  } u;
-  int marked;   /* for garbage collection; never collect (nor change) if > 1 */
-  char str[1];   /* \0 byte already reserved */
-} TaggedString;
+
+typedef struct TObject {
+  lua_Type ttype;
+  Value value;
+} TObject;
 
 
 
@@ -65,6 +78,27 @@ typedef struct GCnode {
 } GCnode;
 
 
+/*
+** String headers for string table
+*/
+
+typedef struct TaggedString {
+  GCnode head;
+  int constindex;  /* hint to reuse constants (= -1 if this is a userdata) */
+  unsigned long hash;
+  union {
+    TObject globalval;
+    struct {
+      void *v;  /* if this is a userdata, here is its value */
+      int tag;
+    } d;
+  } u;
+  char str[1];   /* \0 byte already reserved */
+} TaggedString;
+
+
+
+
 /*
 ** Function Prototypes
 */
@@ -87,43 +121,6 @@ typedef struct LocVar {
 
 
 
-/*
-** Lua TYPES
-** WARNING: if you change the order of this enumeration,
-** grep "ORDER LUA_T"
-*/
-typedef enum {
-  LUA_T_NIL      = -10,
-  LUA_T_NUMBER   = -9,
-  LUA_T_STRING   = -8,
-  LUA_T_ARRAY    = -7,  /* array==table */
-  LUA_T_PROTO    = -6,
-  LUA_T_FUNCTION = -5,
-  LUA_T_CFUNCTION= -4,
-  LUA_T_MARK     = -3,
-  LUA_T_CMARK    = -2,
-  LUA_T_LINE     = -1,
-  LUA_T_USERDATA = 0
-} lua_Type;
-
-#define NUM_TYPES 11
-
-
-typedef union {
-  lua_CFunction f;
-  real n;
-  TaggedString *ts;
-  TProtoFunc *tf;
-  struct Closure *cl;
-  struct Hash *a;
-  int i;
-} Value;
-
-typedef struct TObject {
-  lua_Type ttype;
-  Value value;
-} TObject;
-
 
 /* Macros to access structure members */
 #define ttype(o)        ((o)->ttype)

+ 65 - 19
lstring.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lstring.c,v 1.1 1997/08/14 20:23:30 roberto Exp $
+** $Id: lstring.c,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $
 ** String table (keep all strings handled by Lua)
 ** See Copyright Notice in lua.h
 */
@@ -15,6 +15,10 @@
 
 #define NUM_HASHS  61
 
+
+GCnode luaS_root = {NULL, 0};  /* list of global variables */
+
+
 typedef struct {
   int size;
   int nuse;  /* number of elements (including EMPTYs) */
@@ -39,7 +43,7 @@ static stringtable string_root[NUM_HASHS] = {
 };
 
 
-static TaggedString EMPTY = {LUA_T_STRING, {0}, {{NOT_USED, NOT_USED}}, 2, {0}};
+static TaggedString EMPTY = {{NULL, 2}, 0, 0L, {{LUA_T_NIL, {NULL}}}, {0}};
 
 
 
@@ -68,7 +72,7 @@ static void grow (stringtable *tb)
   tb->nuse = 0;
   for (i=0; i<tb->size; i++) {
     if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) {
-      int h = tb->hash[i]->uu.hash%newsize;
+      int h = tb->hash[i]->hash%newsize;
       while (newhash[h])
         h = (h+1)%newsize;
       newhash[h] = tb->hash[i];
@@ -87,16 +91,18 @@ static TaggedString *newone(char *buff, int tag, unsigned long h)
   if (tag == LUA_T_STRING) {
     ts = (TaggedString *)luaM_malloc(sizeof(TaggedString)+strlen(buff));
     strcpy(ts->str, buff);
-    ts->u.s.varindex = ts->u.s.constindex = NOT_USED;
-    ts->tag = LUA_T_STRING;
+    ts->u.globalval.ttype = LUA_T_NIL;  /* initialize global value */
+    ts->constindex = 0;
   }
   else {
     ts = (TaggedString *)luaM_malloc(sizeof(TaggedString));
-    ts->u.v = buff;
-    ts->tag = tag == LUA_ANYTAG ? 0 : tag;
+    ts->u.d.v = buff;
+    ts->u.d.tag = tag == LUA_ANYTAG ? 0 : tag;
+    ts->constindex = -1;  /* tag -> this is a userdata */
   }
-  ts->marked = 0;
-  ts->uu.hash = h;
+  ts->head.marked = 0;
+  ts->head.next = (GCnode *)ts;  /* signal it is in no list */
+  ts->hash = h;
   return ts;
 }
 
@@ -113,9 +119,9 @@ static TaggedString *insert (char *buff, int tag, stringtable *tb)
   {
     if (ts == &EMPTY)
       j = i;
-    else if ((ts->tag == LUA_T_STRING) ?
+    else if ((ts->constindex >= 0) ?  /* is a string? */
               (tag == LUA_T_STRING && (strcmp(buff, ts->str) == 0)) :
-              ((tag == ts->tag || tag == LUA_ANYTAG) && buff == ts->u.v))
+              ((tag == ts->u.d.tag || tag == LUA_ANYTAG) && buff == ts->u.d.v))
       return ts;
     i = (i+1)%tb->size;
   }
@@ -142,8 +148,8 @@ TaggedString *luaS_new (char *str)
 TaggedString *luaS_newfixedstring (char *str)
 {
   TaggedString *ts = luaS_new(str);
-  if (ts->marked == 0)
-    ts->marked = 2;  /* avoid GC */
+  if (ts->head.marked == 0)
+    ts->head.marked = 2;  /* avoid GC */
   return ts;
 }
 
@@ -151,7 +157,7 @@ TaggedString *luaS_newfixedstring (char *str)
 void luaS_free (TaggedString *l)
 {
   while (l) {
-    TaggedString *next = l->uu.next;
+    TaggedString *next = (TaggedString *)l->head.next;
     luaM_free(l);
     l = next;
   }
@@ -159,22 +165,35 @@ void luaS_free (TaggedString *l)
 
 
 /*
-** Garbage collection function.
+** Garbage collection functions.
 */
+
+static void remove_from_list (GCnode *l)
+{
+  while (l) {
+    GCnode *next = l->next;
+    while (next && !next->marked)
+      next = l->next = next->next;
+    l = next;
+  }
+}
+
+
 TaggedString *luaS_collector (void)
 {
   TaggedString *frees = NULL;
   int i;
+  remove_from_list(&luaS_root);
   for (i=0; i<NUM_HASHS; i++) {
     stringtable *tb = &string_root[i];
     int j;
     for (j=0; j<tb->size; j++) {
       TaggedString *t = tb->hash[j];
       if (t == NULL) continue;
-      if (t->marked == 1)
-        t->marked = 0;
-      else if (!t->marked) {
-        t->uu.next = frees;
+      if (t->head.marked == 1)
+        t->head.marked = 0;
+      else if (!t->head.marked) {
+        t->head.next = (GCnode *)frees;
         frees = t;
         tb->hash[j] = &EMPTY;
         --luaO_nentities;
@@ -184,3 +203,30 @@ TaggedString *luaS_collector (void)
   return frees;
 }
 
+
+void luaS_rawsetglobal (TaggedString *ts, TObject *newval)
+{
+  ts->u.globalval = *newval;
+  if (ts->head.next == (GCnode *)ts) {  /* is not in list? */
+    ts->head.next = luaS_root.next;
+    luaS_root.next = (GCnode *)ts;
+  }
+}
+
+
+char *luaS_travsymbol (int (*fn)(TObject *))
+{
+  TaggedString *g;
+  for (g=(TaggedString *)luaS_root.next; g; g=(TaggedString *)g->head.next)
+    if (fn(&g->u.globalval))
+      return g->str;
+  return NULL;
+}
+
+
+int luaS_globaldefined (char *name)
+{
+  TaggedString *ts = luaS_new(name);
+  return ts->u.globalval.ttype != LUA_T_NIL;
+}
+

+ 5 - 1
lstring.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lstring.h,v 1.1 1997/08/14 20:23:40 roberto Exp roberto $
+** $Id: lstring.h,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $
 ** String table (keep all strings handled by Lua)
 ** See Copyright Notice in lua.h
 */
@@ -10,6 +10,7 @@
 
 #include "lobject.h"
 
+extern GCnode luaS_root;
 
 TaggedString *luaS_createudata (void *udata, int tag);
 TaggedString *luaS_collector (void);
@@ -17,5 +18,8 @@ void luaS_free (TaggedString *l);
 void luaS_callIM (TaggedString *l);
 TaggedString *luaS_new (char *str);
 TaggedString *luaS_newfixedstring (char *str);
+void luaS_rawsetglobal (TaggedString *ts, TObject *newval);
+char *luaS_travsymbol (int (*fn)(TObject *));
+int luaS_globaldefined (char *name);
 
 #endif

+ 2 - 2
ltm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: $
+** $Id: ltm.c,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $
 ** Tag methods
 ** See Copyright Notice in lua.h
 */
@@ -176,7 +176,7 @@ int luaT_efectivetag (TObject *o)
 {
   lua_Type t = ttype(o);
   if (t == LUA_T_USERDATA) {
-    int tag = o->value.ts->tag;
+    int tag = o->value.ts->u.d.tag;
     return (tag >= 0) ? LUA_T_USERDATA : tag;
   }
   else if (t == LUA_T_ARRAY)

+ 4 - 4
lua.stx

@@ -1,6 +1,6 @@
 %{
 /*
-** $Id: lua.stx,v 1.4 1997/09/22 20:53:20 roberto Exp roberto $
+** $Id: lua.stx,v 1.5 1997/09/24 19:43:11 roberto Exp roberto $
 ** Syntax analizer and code generator
 ** See Copyright Notice in lua.h
 */
@@ -203,13 +203,13 @@ static int next_constant (State *cs)
 static int string_constant (TaggedString *s, State *cs)
 {
   TProtoFunc *f = cs->f;
-  int c = s->u.s.constindex;
-  if (!(0 <= c && c < f->nconsts &&
+  int c = s->constindex;
+  if (!(c < f->nconsts &&
       ttype(&f->consts[c]) == LUA_T_STRING && tsvalue(&f->consts[c]) == s)) {
     c = next_constant(cs);
     ttype(&f->consts[c]) = LUA_T_STRING;
     tsvalue(&f->consts[c]) = s;
-    s->u.s.constindex = c;  /* hint for next time */
+    s->constindex = c;  /* hint for next time */
   }
   return c;
 }

+ 10 - 11
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 1.4 1997/09/22 20:53:20 roberto Exp roberto $
+** $Id: lvm.c,v 1.5 1997/09/24 19:43:11 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -12,7 +12,6 @@
 #include "ldo.h"
 #include "lfunc.h"
 #include "lgc.h"
-#include "lglobal.h"
 #include "lmem.h"
 #include "lopcodes.h"
 #include "lstring.h"
@@ -155,17 +154,17 @@ void luaV_settable (TObject *t, int mode)
 }
 
 
-void luaV_getglobal (Word n)
+void luaV_getglobal (TaggedString *ts)
 {
   /* WARNING: caller must assure stack space */
-  TObject *value = &luaG_global[n].object;
+  TObject *value = &ts->u.globalval;
   TObject *im = luaT_getimbyObj(value, IM_GETGLOBAL);
   if (ttype(im) == LUA_T_NIL) {  /* default behavior */
     *luaD_stack.top++ = *value;
   }
   else {
     ttype(luaD_stack.top) = LUA_T_STRING;
-    tsvalue(luaD_stack.top) = luaG_global[n].varname;
+    tsvalue(luaD_stack.top) = ts;
     luaD_stack.top++;
     *luaD_stack.top++ = *value;
     luaD_callTM(im, 2, 1);
@@ -173,17 +172,17 @@ void luaV_getglobal (Word n)
 }
 
 
-void luaV_setglobal (Word n)
+void luaV_setglobal (TaggedString *ts)
 {
-  TObject *oldvalue = &luaG_global[n].object;
+  TObject *oldvalue = &ts->u.globalval;
   TObject *im = luaT_getimbyObj(oldvalue, IM_SETGLOBAL);
   if (ttype(im) == LUA_T_NIL)  /* default behavior */
-    s_object(n) = *(--luaD_stack.top);
+    luaS_rawsetglobal(ts, --luaD_stack.top);
   else {
     /* WARNING: caller must assure stack space */
     TObject newvalue = *(luaD_stack.top-1);
     ttype(luaD_stack.top-1) = LUA_T_STRING;
-    tsvalue(luaD_stack.top-1) = luaG_global[n].varname;
+    tsvalue(luaD_stack.top-1) = ts;
     *luaD_stack.top++ = *oldvalue;
     *luaD_stack.top++ = newvalue;
     luaD_callTM(im, 3, 0);
@@ -334,7 +333,7 @@ StkId luaV_execute (Closure *cl, StkId base)
       case GETGLOBAL9:
         aux -= GETGLOBAL0;
       getglobal:
-        luaV_getglobal(luaG_findsymbol(tsvalue(&consts[aux])));
+        luaV_getglobal(tsvalue(&consts[aux]));
         break;
 
       case GETTABLE:
@@ -396,7 +395,7 @@ StkId luaV_execute (Closure *cl, StkId base)
       case SETGLOBALB:
         aux = *pc++;
       setglobal:
-        luaV_setglobal(luaG_findsymbol(tsvalue(&consts[aux])));
+        luaV_setglobal(tsvalue(&consts[aux]));
         break;
 
       case SETTABLE0:

+ 3 - 3
lvm.h

@@ -1,5 +1,5 @@
 /*
-** $Id: $
+** $Id: lvm.h,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -21,8 +21,8 @@ int luaV_tonumber (TObject *obj);
 int luaV_tostring (TObject *obj);
 void luaV_gettable (void);
 void luaV_settable (TObject *t, int mode);
-void luaV_getglobal (Word n);
-void luaV_setglobal (Word n);
+void luaV_getglobal (TaggedString *ts);
+void luaV_setglobal (TaggedString *ts);
 StkId luaV_execute (Closure *func, StkId base);
 void luaV_closure (void);
 

+ 15 - 18
makefile

@@ -1,5 +1,5 @@
 #
-## $Id: $
+## $Id: makefile,v 1.1 1997/09/16 19:33:21 roberto Exp roberto $
 ## Makefile
 ## See Copyright Notice in lua.h
 #
@@ -18,7 +18,7 @@
 # define LUA_COMPAT2_5=0 if yous system does not need to be compatible with
 # version 2.5 (or older)
 
-CONFIG = -DPOPEN -D_POSIX_SOURCE 
+CONFIG = -DPOPEN -D_POSIX_SOURCE
 #CONFIG = -DLUA_COMPAT2_5=0 -DOLD_ANSI -DDEBUG
 
 
@@ -40,7 +40,6 @@ LUAOBJS = \
 	ldo.o \
 	lfunc.o \
 	lgc.o \
-	lglobal.o \
 	llex.o \
 	lmem.o \
 	lobject.o \
@@ -96,31 +95,29 @@ clear	:
 
 
 lapi.o: lapi.c lapi.h lua.h lobject.h lauxlib.h ldo.h lfunc.h lgc.h \
- lglobal.h lmem.h lstring.h ltable.h ltm.h luadebug.h lvm.h
+ lmem.h lstring.h ltable.h ltm.h luadebug.h lvm.h
 lauxlib.o: lauxlib.c lauxlib.h lua.h luadebug.h
 lbuiltin.o: lbuiltin.c lapi.h lua.h lobject.h lauxlib.h lbuiltin.h \
- lglobal.h lmem.h lstring.h ltable.h ltm.h
-ldo.o: ldo.c ldo.h lobject.h lua.h lgc.h lmem.h lparser.h lzio.h ltm.h \
- luadebug.h lundump.h lvm.h
+ lmem.h lstring.h ltable.h ltm.h
+ldo.o: ldo.c lbuiltin.h ldo.h lobject.h lua.h lgc.h lmem.h lparser.h \
+ lzio.h ltm.h luadebug.h lundump.h lvm.h
 lfunc.o: lfunc.c lfunc.h lobject.h lua.h lmem.h
-lgc.o: lgc.c ldo.h lobject.h lua.h lfunc.h lgc.h lglobal.h lmem.h \
- lstring.h ltable.h ltm.h
-lglobal.o: lglobal.c lbuiltin.h lglobal.h lobject.h lua.h lmem.h \
- lstring.h
+lgc.o: lgc.c ldo.h lobject.h lua.h lfunc.h lgc.h lmem.h lstring.h \
+ ltable.h ltm.h
 liolib.o: liolib.c lauxlib.h lua.h luadebug.h lualib.h
-llex.o: llex.c lglobal.h lobject.h lua.h llex.h lzio.h lmem.h \
- lparser.h lstring.h ltokens.h luadebug.h
+llex.o: llex.c llex.h lobject.h lua.h lzio.h lmem.h lparser.h \
+ lstring.h ltokens.h luadebug.h
 lmathlib.o: lmathlib.c lauxlib.h lua.h lualib.h
 lmem.o: lmem.c lmem.h lua.h
 lobject.o: lobject.c lobject.h lua.h
-lparser.o: lparser.c lauxlib.h lua.h ldo.h lobject.h lfunc.h lglobal.h \
- llex.h lzio.h lmem.h lopcodes.h lparser.h lstring.h luadebug.h
+lparser.o: lparser.c lauxlib.h lua.h ldo.h lobject.h lfunc.h llex.h \
+ lzio.h lmem.h lopcodes.h lparser.h lstring.h luadebug.h
 lstring.o: lstring.c lmem.h lobject.h lua.h lstring.h
 lstrlib.o: lstrlib.c lauxlib.h lua.h lualib.h
 ltable.o: ltable.c lauxlib.h lua.h lmem.h lobject.h ltable.h
 ltm.o: ltm.c lauxlib.h lua.h ldo.h lobject.h lmem.h ltm.h lapi.h
-lua.o: lua.c lua.h lualib.h luadebug.h
+lua.o: lua.c lua.h luadebug.h lualib.h
 lundump.o: lundump.c lundump.h lobject.h lua.h lzio.h
-lvm.o: lvm.c lauxlib.h lua.h ldo.h lobject.h lfunc.h lgc.h lglobal.h \
- lmem.h lopcodes.h lstring.h ltable.h ltm.h luadebug.h lvm.h
+lvm.o: lvm.c lauxlib.h lua.h ldo.h lobject.h lfunc.h lgc.h lmem.h \
+ lopcodes.h lstring.h ltable.h ltm.h luadebug.h lvm.h
 lzio.o: lzio.c lzio.h