Browse Source

new implementation for globals: Global value is stored in TaggedString

Roberto Ierusalimschy 28 năm trước cách đây
mục cha
commit
a580480b07
17 tập tin đã thay đổi với 251 bổ sung288 xóa
  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