new implementation for globals: Global value is stored in TaggedString

This commit is contained in:
Roberto Ierusalimschy 1997-09-26 12:02:26 -03:00
parent 0dd6d1080e
commit a580480b07
17 changed files with 259 additions and 296 deletions

22
lapi.c
View File

@ -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 "";
}

View File

@ -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);
}

View File

@ -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, ...);

View File

@ -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);
}

4
ldo.c
View File

@ -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();
}

31
lgc.c
View File

@ -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 */
}

View File

@ -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;
}

View File

@ -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

11
llex.c
View File

@ -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;
}

129
lobject.h
View File

@ -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,64 +29,6 @@ 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
*/
#define NOT_USED 0xFFFE
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;
/*
** generic header for garbage collector lists
*/
typedef struct GCnode {
struct GCnode *next;
int marked;
} GCnode;
/*
** Function Prototypes
*/
typedef struct TProtoFunc {
GCnode head;
Byte *code; /* ends with opcode ENDCODE */
int lineDefined;
TaggedString *fileName;
struct TObject *consts;
int nconsts;
struct LocVar *locvars; /* ends with line = -1 */
int nupvalues;
} TProtoFunc;
typedef struct LocVar {
TaggedString *varname; /* NULL signals end of scope */
int line;
} LocVar;
/*
** Lua TYPES
** WARNING: if you change the order of this enumeration,
@ -110,21 +52,76 @@ typedef enum {
typedef union {
lua_CFunction f;
real n;
TaggedString *ts;
TProtoFunc *tf;
struct Closure *cl;
struct Hash *a;
int i;
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 TObject {
lua_Type ttype;
Value value;
} TObject;
/*
** generic header for garbage collector lists
*/
typedef struct GCnode {
struct GCnode *next;
int marked;
} 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
*/
typedef struct TProtoFunc {
GCnode head;
Byte *code; /* ends with opcode ENDCODE */
int lineDefined;
TaggedString *fileName;
struct TObject *consts;
int nconsts;
struct LocVar *locvars; /* ends with line = -1 */
int nupvalues;
} TProtoFunc;
typedef struct LocVar {
TaggedString *varname; /* NULL signals end of scope */
int line;
} LocVar;
/* Macros to access structure members */
#define ttype(o) ((o)->ttype)
#define nvalue(o) ((o)->value.n)

View File

@ -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;
}

View File

@ -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

4
ltm.c
View File

@ -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)

View File

@ -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;
}

21
lvm.c
View File

@ -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:

6
lvm.h
View File

@ -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);

View File

@ -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