summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-05-08 16:32:53 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-05-08 16:32:53 -0300
commit11a70220670f25a9929439f0b27331f09f05235c (patch)
treec4a962b5a3e53ac6df8894fb3ad2248c4a1256cb
parent35a6ed283881f313152457f24cc6c677122d5058 (diff)
downloadlua-github-11a70220670f25a9929439f0b27331f09f05235c.tar.gz
global variables are stored in a Lua table
-rw-r--r--lapi.c78
-rw-r--r--lapi.h3
-rw-r--r--lbuiltin.c102
-rw-r--r--lbuiltin.h7
-rw-r--r--lcode.c10
-rw-r--r--ldebug.c11
-rw-r--r--ldo.c5
-rw-r--r--lgc.c31
-rw-r--r--llex.c11
-rw-r--r--lobject.h12
-rw-r--r--lstate.c6
-rw-r--r--lstate.h6
-rw-r--r--lstring.c65
-rw-r--r--lstring.h7
-rw-r--r--ltable.c22
-rw-r--r--ltable.h6
-rw-r--r--ltests.c7
-rw-r--r--lua.h13
-rw-r--r--lundump.c5
-rw-r--r--lvm.c40
-rw-r--r--lvm.h7
21 files changed, 180 insertions, 274 deletions
diff --git a/lapi.c b/lapi.c
index 6685abdc..60a9b45c 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
/*
-** $Id: lapi.c,v 1.77 2000/03/29 20:19:20 roberto Exp roberto $
+** $Id: lapi.c,v 1.78 2000/04/17 19:23:12 roberto Exp roberto $
** Lua API
** See Copyright Notice in lua.h
*/
@@ -65,6 +65,20 @@ lua_Object lua_pop (lua_State *L) {
}
+void lua_pushglobaltable (lua_State *L) {
+ avalue(L->top) = L->gt;
+ ttype(L->top) = TAG_TABLE;
+ incr_top;
+}
+
+
+void lua_setglobaltable (lua_State *L, lua_Object newtable) {
+ if (lua_type(L, newtable)[0] != 't') /* type == "table"? */
+ lua_error(L, "Lua API error - invalid value for global table");
+ L->gt = avalue(newtable);
+}
+
+
/*
** Get a parameter, returning the object handle or LUA_NOOBJECT on error.
** `number' must be 1 to get the first parameter.
@@ -131,7 +145,10 @@ void lua_settable (lua_State *L) {
void lua_rawsettable (lua_State *L) {
luaA_checkCargs(L, 3);
- luaV_rawsettable(L, L->top-3);
+ if (ttype(L->top-3) != TAG_TABLE)
+ lua_error(L, "indexed expression not a table");
+ luaH_set(L, avalue(L->top-3), L->top-2, L->top-1);
+ L->top -= 3;
}
@@ -145,27 +162,32 @@ lua_Object lua_createtable (lua_State *L) {
lua_Object lua_getglobal (lua_State *L, const char *name) {
- luaV_getglobal(L, luaS_assertglobalbyname(L, name), L->top++);
+ luaV_getglobal(L, luaS_new(L, name), L->top++);
return luaA_putObjectOnTop(L);
}
-lua_Object lua_rawgetglobal (lua_State *L, const char *name) {
- GlobalVar *gv = luaS_assertglobalbyname(L, name);
- return luaA_putluaObject(L, &gv->value);
+void lua_setglobal (lua_State *L, const char *name) {
+ luaA_checkCargs(L, 1);
+ luaV_setglobal(L, luaS_new(L, name), L->top--);
}
-void lua_setglobal (lua_State *L, const char *name) {
- luaA_checkCargs(L, 1);
- luaV_setglobal(L, luaS_assertglobalbyname(L, name), L->top--);
+/* deprecated */
+lua_Object lua_rawgetglobal (lua_State *L, const char *name) {
+ lua_pushglobaltable(L);
+ lua_pushstring(L, name);
+ return lua_rawgettable(L);
}
+/* deprecated */
void lua_rawsetglobal (lua_State *L, const char *name) {
- GlobalVar *gv = luaS_assertglobalbyname(L, name);
+ TObject key;
luaA_checkCargs(L, 1);
- gv->value = *(--L->top);
+ ttype(&key) = TAG_STRING;
+ tsvalue(&key) = luaS_new(L, name);
+ luaH_set(L, L->gt, &key, --L->top);
}
@@ -334,40 +356,6 @@ void lua_settag (lua_State *L, int tag) {
}
-GlobalVar *luaA_nextvar (lua_State *L, TString *ts) {
- GlobalVar *gv;
- if (ts == NULL)
- gv = L->rootglobal; /* first variable */
- else {
- /* check whether name is in global var list */
- luaL_arg_check(L, ts->u.s.gv, 1, "variable name expected");
- gv = ts->u.s.gv->next; /* get next */
- }
- while (gv && gv->value.ttype == TAG_NIL) /* skip globals with nil */
- gv = gv->next;
- if (gv) {
- ttype(L->top) = TAG_STRING; tsvalue(L->top) = gv->name;
- incr_top;
- luaA_pushobject(L, &gv->value);
- }
- return gv;
-}
-
-
-const char *lua_nextvar (lua_State *L, const char *varname) {
- TString *ts = (varname == NULL) ? NULL : luaS_new(L, varname);
- GlobalVar *gv = luaA_nextvar(L, ts);
- if (gv) {
- top2LC(L, 2);
- return gv->name->str;
- }
- else {
- top2LC(L, 0);
- return NULL;
- }
-}
-
-
int luaA_next (lua_State *L, const Hash *t, int i) {
int tsize = t->size;
for (; i<tsize; i++) {
diff --git a/lapi.h b/lapi.h
index 7f43c2a0..ec0fa707 100644
--- a/lapi.h
+++ b/lapi.h
@@ -1,5 +1,5 @@
/*
-** $Id: lapi.h,v 1.15 2000/03/10 18:37:44 roberto Exp roberto $
+** $Id: lapi.h,v 1.16 2000/03/29 20:19:20 roberto Exp roberto $
** Auxiliary functions from Lua API
** See Copyright Notice in lua.h
*/
@@ -13,7 +13,6 @@
void luaA_checkCargs (lua_State *L, int nargs);
void luaA_pushobject (lua_State *L, const TObject *o);
-GlobalVar *luaA_nextvar (lua_State *L, TString *g);
int luaA_next (lua_State *L, const Hash *t, int i);
lua_Object luaA_putluaObject (lua_State *L, const TObject *o);
lua_Object luaA_putObjectOnTop (lua_State *L);
diff --git a/lbuiltin.c b/lbuiltin.c
index d57f9fa2..060127f7 100644
--- a/lbuiltin.c
+++ b/lbuiltin.c
@@ -1,5 +1,5 @@
/*
-** $Id: lbuiltin.c,v 1.106 2000/04/17 19:23:12 roberto Exp roberto $
+** $Id: lbuiltin.c,v 1.107 2000/04/25 16:55:09 roberto Exp roberto $
** Built-in functions
** See Copyright Notice in lua.h
*/
@@ -52,13 +52,6 @@ void luaB_opentests (lua_State *L);
*/
-static void pushtagstring (lua_State *L, TString *s) {
- ttype(L->top) = TAG_STRING;
- tsvalue(L->top) = s;
- incr_top;
-}
-
-
static Number getsize (const Hash *h) {
Number max = 0;
int i = h->size;
@@ -191,21 +184,10 @@ void luaB_setglobal (lua_State *L) {
lua_setglobal(L, name);
}
-void luaB_rawsetglobal (lua_State *L) {
- const char *name = luaL_check_string(L, 1);
- lua_Object value = luaL_nonnullarg(L, 2);
- lua_pushobject(L, value);
- lua_rawsetglobal(L, name);
-}
-
void luaB_getglobal (lua_State *L) {
lua_pushobject(L, lua_getglobal(L, luaL_check_string(L, 1)));
}
-void luaB_rawgetglobal (lua_State *L) {
- lua_pushobject(L, lua_rawgetglobal(L, luaL_check_string(L, 1)));
-}
-
void luaB_tag (lua_State *L) {
lua_pushnumber(L, lua_tag(L, luaL_nonnullarg(L, 1)));
}
@@ -226,6 +208,12 @@ void luaB_copytagmethods (lua_State *L) {
luaL_check_int(L, 2)));
}
+void luaB_globals (lua_State *L) {
+ lua_pushglobaltable(L);
+ if (lua_getparam(L, 1) != LUA_NOOBJECT)
+ lua_setglobaltable(L, luaL_tablearg(L, 1));
+}
+
void luaB_rawgettable (lua_State *L) {
lua_pushobject(L, luaL_nonnullarg(L, 1));
lua_pushobject(L, luaL_nonnullarg(L, 2));
@@ -346,20 +334,6 @@ void luaB_call (lua_State *L) {
}
-void luaB_nextvar (lua_State *L) {
- lua_Object o = lua_getparam(L, 1);
- TString *name;
- if (o == LUA_NOOBJECT || ttype(o) == TAG_NIL)
- name = NULL;
- else {
- luaL_arg_check(L, ttype(o) == TAG_STRING, 1, "variable name expected");
- name = tsvalue(o);
- }
- if (!luaA_nextvar(L, name))
- lua_pushnil(L);
-}
-
-
void luaB_next (lua_State *L) {
const Hash *a = gettable(L, 1);
lua_Object k = lua_getparam(L, 2);
@@ -463,28 +437,6 @@ void luaB_foreach (lua_State *L) {
}
-void luaB_foreachvar (lua_State *L) {
- lua_Object f = luaL_functionarg(L, 1);
- GlobalVar *gv;
- luaD_checkstack(L, 4); /* for extra var name, f, var name, and globalval */
- for (gv = L->rootglobal; gv; gv = gv->next) {
- if (gv->value.ttype != TAG_NIL) {
- pushtagstring(L, gv->name); /* keep (extra) name on stack to avoid GC */
- *(L->top++) = *f;
- pushtagstring(L, gv->name);
- *(L->top++) = gv->value;
- luaD_call(L, L->top-3, 1);
- if (ttype(L->top-1) != TAG_NIL) {
- *(L->top-2) = *(L->top-1); /* remove extra name */
- L->top--;
- return;
- }
- L->top-=2; /* remove result and extra name */
- }
- }
-}
-
-
void luaB_getn (lua_State *L) {
lua_pushnumber(L, getnarg(L, gettable(L, 1)));
}
@@ -610,6 +562,39 @@ void luaB_sort (lua_State *L) {
/* }====================================================== */
+/*
+** {======================================================
+** Deprecated functions to manipulate global environment:
+** all of them can be simulated through table operations
+** over the global table.
+** =======================================================
+*/
+
+#define num_deprecated 4
+
+static const struct luaL_reg deprecated_global_funcs[num_deprecated] = {
+ {"foreachvar", luaB_foreach},
+ {"nextvar", luaB_next},
+ {"rawgetglobal", luaB_rawgettable},
+ {"rawsetglobal", luaB_rawsettable}
+};
+
+
+
+static void deprecated_funcs (lua_State *L) {
+ TObject gt;
+ int i;
+ ttype(&gt) = TAG_TABLE;
+ avalue(&gt) = L->gt;
+ for (i=0; i<num_deprecated; i++) {
+ lua_pushobject(L, &gt);
+ lua_pushcclosure(L, deprecated_global_funcs[i].func, 1);
+ lua_setglobal(L, deprecated_global_funcs[i].name);
+ }
+}
+
+/* }====================================================== */
+
static const struct luaL_reg builtin_funcs[] = {
{"_ALERT", luaB__ALERT},
{"_ERRORMESSAGE", luaB__ERRORMESSAGE},
@@ -621,13 +606,11 @@ static const struct luaL_reg builtin_funcs[] = {
{"error", luaB_error},
{"getglobal", luaB_getglobal},
{"gettagmethod", luaB_gettagmethod},
+ {"globals", luaB_globals},
{"newtag", luaB_newtag},
{"next", luaB_next},
- {"nextvar", luaB_nextvar},
{"print", luaB_print},
- {"rawgetglobal", luaB_rawgetglobal},
{"rawgettable", luaB_rawgettable},
- {"rawsetglobal", luaB_rawsetglobal},
{"rawsettable", luaB_rawsettable},
{"setglobal", luaB_setglobal},
{"settag", luaB_settag},
@@ -640,7 +623,6 @@ static const struct luaL_reg builtin_funcs[] = {
{"assert", luaB_assert},
{"foreach", luaB_foreach},
{"foreachi", luaB_foreachi},
- {"foreachvar", luaB_foreachvar},
{"getn", luaB_getn},
{"sort", luaB_sort},
{"tinsert", luaB_tinsert},
@@ -648,6 +630,7 @@ static const struct luaL_reg builtin_funcs[] = {
};
+
void luaB_predefine (lua_State *L) {
/* pre-register mem error messages, to avoid loop when error arises */
luaS_newfixed(L, tableEM);
@@ -658,5 +641,6 @@ void luaB_predefine (lua_State *L) {
#endif
lua_pushstring(L, LUA_VERSION);
lua_setglobal(L, "_VERSION");
+ deprecated_funcs(L);
}
diff --git a/lbuiltin.h b/lbuiltin.h
index bf2376d3..2bf34105 100644
--- a/lbuiltin.h
+++ b/lbuiltin.h
@@ -1,5 +1,5 @@
/*
-** $Id: lbuiltin.h,v 1.6 2000/03/03 14:58:26 roberto Exp roberto $
+** $Id: lbuiltin.h,v 1.7 2000/04/17 19:23:12 roberto Exp roberto $
** Built-in functions
** See Copyright Notice in lua.h
*/
@@ -20,17 +20,14 @@ void luaB_dostring (lua_State *L);
void luaB_error (lua_State *L);
void luaB_foreach (lua_State *L);
void luaB_foreachi (lua_State *L);
-void luaB_foreachvar (lua_State *L);
void luaB_getglobal (lua_State *L);
void luaB_getn (lua_State *L);
void luaB_gettagmethod (lua_State *L);
+void luaB_globals (lua_State *L);
void luaB_newtag (lua_State *L);
void luaB_next (lua_State *L);
-void luaB_nextvar (lua_State *L);
void luaB_print (lua_State *L);
-void luaB_rawgetglobal (lua_State *L);
void luaB_rawgettable (lua_State *L);
-void luaB_rawsetglobal (lua_State *L);
void luaB_rawsettable (lua_State *L);
void luaB_setglobal (lua_State *L);
void luaB_settag (lua_State *L);
diff --git a/lcode.c b/lcode.c
index 296d5cf3..b5ef968e 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
/*
-** $Id: lcode.c,v 1.27 2000/04/17 14:05:34 roberto Exp roberto $
+** $Id: lcode.c,v 1.28 2000/04/19 13:41:37 roberto Exp roberto $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -16,7 +16,6 @@
#include "lobject.h"
#include "lopcodes.h"
#include "lparser.h"
-#include "lstring.h"
void luaK_error (LexState *ls, const char *msg) {
@@ -148,11 +147,6 @@ void luaK_setcallreturns (FuncState *fs, int nresults) {
}
-static void assertglobal (FuncState *fs, int index) {
- luaS_assertglobal(fs->L, fs->f->kstr[index]);
-}
-
-
static int discharge (FuncState *fs, expdesc *var) {
switch (var->k) {
case VLOCAL:
@@ -160,7 +154,6 @@ static int discharge (FuncState *fs, expdesc *var) {
break;
case VGLOBAL:
luaK_code1(fs, OP_GETGLOBAL, var->u.index);
- assertglobal(fs, var->u.index); /* make sure that there is a global */
break;
case VINDEXED:
luaK_code0(fs, OP_GETTABLE);
@@ -190,7 +183,6 @@ void luaK_storevar (LexState *ls, const expdesc *var) {
break;
case VGLOBAL:
luaK_code1(fs, OP_SETGLOBAL, var->u.index);
- assertglobal(fs, var->u.index); /* make sure that there is a global */
break;
case VINDEXED: /* table is at top-3; pop 3 elements after operation */
luaK_code2(fs, OP_SETTABLE, 3, 3);
diff --git a/ldebug.c b/ldebug.c
index ef934d86..3a381455 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldebug.c,v 1.15 2000/03/30 17:19:48 roberto Exp roberto $
+** $Id: ldebug.c,v 1.16 2000/03/30 20:55:50 roberto Exp roberto $
** Debug Interface
** See Copyright Notice in lua.h
*/
@@ -159,12 +159,13 @@ static int checkfunc (lua_State *L, TObject *o) {
static void lua_getobjname (lua_State *L, StkId f, lua_Debug *ar) {
- GlobalVar *g;
+ Hash *g = L->gt;
+ int i;
/* try to find a name for given function */
setnormalized(L->top, f); /* to be used by `checkfunc' */
- for (g=L->rootglobal; g; g=g->next) {
- if (checkfunc(L, &g->value)) {
- ar->name = g->name->str;
+ for (i=0; i<=g->size; i++) {
+ if (checkfunc(L, val(node(g,i))) && ttype(key(node(g,i))) == TAG_STRING) {
+ ar->name = tsvalue(key(node(g,i)))->str;
ar->namewhat = "global";
return;
}
diff --git a/ldo.c b/ldo.c
index 9791c7f5..edbaab85 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldo.c,v 1.72 2000/03/30 20:55:50 roberto Exp roberto $
+** $Id: ldo.c,v 1.73 2000/04/14 18:12:35 roberto Exp roberto $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -21,6 +21,7 @@
#include "lparser.h"
#include "lstate.h"
#include "lstring.h"
+#include "ltable.h"
#include "ltm.h"
#include "lua.h"
#include "luadebug.h"
@@ -222,7 +223,7 @@ void luaD_call (lua_State *L, StkId func, int nResults) {
static void message (lua_State *L, const char *s) {
- const TObject *em = &(luaS_assertglobalbyname(L, "_ERRORMESSAGE")->value);
+ const TObject *em = luaH_getglobal(L, "_ERRORMESSAGE");
if (*luaO_typename(em) == 'f') {
*L->top = *em;
incr_top;
diff --git a/lgc.c b/lgc.c
index ac213df2..32dd6471 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
/*
-** $Id: lgc.c,v 1.46 2000/03/30 20:55:50 roberto Exp roberto $
+** $Id: lgc.c,v 1.47 2000/04/14 18:12:35 roberto Exp roberto $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -77,18 +77,6 @@ static void hashmark (lua_State *L, Hash *h) {
}
-static void travglobal (lua_State *L) {
- GlobalVar *gv;
- for (gv=L->rootglobal; gv; gv=gv->next) {
- LUA_ASSERT(L, gv->name->u.s.gv == gv, "inconsistent global name");
- if (gv->value.ttype != TAG_NIL) {
- strmark(L, gv->name); /* cannot collect non nil global variables */
- markobject(L, &gv->value);
- }
- }
-}
-
-
static void travstack (lua_State *L) {
int i;
for (i = (L->top-1)-L->stack; i>=0; i--)
@@ -174,20 +162,6 @@ static void collecttable (lua_State *L) {
/*
-** remove from the global list globals whose names will be collected
-** (the global itself is freed when its name is freed)
-*/
-static void clear_global_list (lua_State *L, int limit) {
- GlobalVar **p = &L->rootglobal;
- GlobalVar *next;
- while ((next = *p) != NULL) {
- if (next->name->marked >= limit) p = &next->next;
- else *p = next->next;
- }
-}
-
-
-/*
** collect all elements with `marked' < `limit'.
** with limit=1, that means all unmarked elements;
** with limit=MAX_INT, that means all elements.
@@ -196,7 +170,6 @@ static void collectstring (lua_State *L, int limit) {
TObject o; /* to call userdata `gc' tag method */
int i;
ttype(&o) = TAG_USERDATA;
- clear_global_list(L, limit);
for (i=0; i<NUM_HASHS; i++) { /* for each hash table */
stringtable *tb = &L->string_root[i];
int j;
@@ -228,7 +201,7 @@ static void collectstring (lua_State *L, int limit) {
static void markall (lua_State *L) {
travstack(L); /* mark stack objects */
- travglobal(L); /* mark global variable values and names */
+ hashmark(L, L->gt); /* mark global variable values and names */
travlock(L); /* mark locked objects */
luaT_travtagmethods(L, markobject); /* mark tag methods */
}
diff --git a/llex.c b/llex.c
index 4efcb873..ae498715 100644
--- a/llex.c
+++ b/llex.c
@@ -1,5 +1,5 @@
/*
-** $Id: llex.c,v 1.56 2000/04/07 13:11:49 roberto Exp roberto $
+** $Id: llex.c,v 1.57 2000/04/12 18:57:19 roberto Exp roberto $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@@ -18,6 +18,7 @@
#include "lparser.h"
#include "lstate.h"
#include "lstring.h"
+#include "ltable.h"
#include "luadebug.h"
#include "lzio.h"
@@ -121,12 +122,18 @@ static void skipspace (LexState *LS) {
}
+static int globaldefined (lua_State *L, const char *name) {
+ const TObject *value = luaH_getglobal(L, name);
+ return ttype(value) != TAG_NIL;
+}
+
+
static int checkcond (lua_State *L, LexState *LS, const char *buff) {
static const char *const opts[] = {"nil", "1", NULL};
int i = luaL_findstring(buff, opts);
if (i >= 0) return i;
else if (isalpha((unsigned char)buff[0]) || buff[0] == '_')
- return luaS_globaldefined(L, buff);
+ return globaldefined(L, buff);
else {
luaX_syntaxerror(LS, "invalid $if condition", buff);
return 0; /* to avoid warnings */
diff --git a/lobject.h b/lobject.h
index 921a7a05..c4e605c6 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
/*
-** $Id: lobject.h,v 1.60 2000/04/10 19:20:24 roberto Exp roberto $
+** $Id: lobject.h,v 1.61 2000/04/25 16:55:09 roberto Exp roberto $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
@@ -85,20 +85,13 @@ typedef struct TObject {
} TObject;
-typedef struct GlobalVar {
- TObject value;
- struct GlobalVar *next;
- struct TString *name;
-} GlobalVar;
-
-
/*
** String headers for string table
*/
typedef struct TString {
union {
struct { /* for strings */
- GlobalVar *gv; /* eventual global value with this name */
+ unsigned long hash;
long len;
} s;
struct { /* for userdata */
@@ -107,7 +100,6 @@ typedef struct TString {
} d;
} u;
struct TString *nexthash; /* chain for hash table */
- unsigned long hash;
int constindex; /* hint to reuse constants (= -1 if this is a userdata) */
unsigned char marked;
char str[1]; /* variable length string!! must be the last field! */
diff --git a/lstate.c b/lstate.c
index f1949df0..7ba9bcff 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.c,v 1.24 2000/01/13 16:30:47 roberto Exp roberto $
+** $Id: lstate.c,v 1.25 2000/03/31 16:28:45 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
@@ -18,6 +18,7 @@
#include "lref.h"
#include "lstate.h"
#include "lstring.h"
+#include "ltable.h"
#include "ltm.h"
@@ -35,7 +36,6 @@ static lua_State *newstate_aux (int stacksize, int put_builtin) {
L->numCblocks = 0;
L->rootproto = NULL;
L->rootcl = NULL;
- L->rootglobal = NULL;
L->roottable = NULL;
L->IMtable = NULL;
L->refArray = NULL;
@@ -47,6 +47,7 @@ static lua_State *newstate_aux (int stacksize, int put_builtin) {
L->callhook = NULL;
L->linehook = NULL;
L->allowhooks = 1;
+ L->gt = luaH_new(L, 10);
luaD_init(L, stacksize);
luaS_init(L);
luaX_init(L);
@@ -87,7 +88,6 @@ void lua_close (lua_State *L) {
luaC_collect(L, 1); /* collect all elements */
LUA_ASSERT(L, L->rootproto == NULL, "list should be empty");
LUA_ASSERT(L, L->rootcl == NULL, "list should be empty");
- LUA_ASSERT(L, L->rootglobal == NULL, "list should be empty");
LUA_ASSERT(L, L->roottable == NULL, "list should be empty");
luaS_freeall(L);
luaM_free(L, L->stack);
diff --git a/lstate.h b/lstate.h
index d099e6aa..6e943b30 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.h,v 1.30 2000/03/10 18:37:44 roberto Exp roberto $
+** $Id: lstate.h,v 1.31 2000/03/30 17:19:48 roberto Exp roberto $
** Global State
** See Copyright Notice in lua.h
*/
@@ -42,7 +42,7 @@ struct C_Lua_Stack {
typedef struct stringtable {
int size;
- int nuse; /* number of elements (including EMPTYs) */
+ int nuse; /* number of elements */
TString **hash;
} stringtable;
@@ -66,8 +66,8 @@ struct lua_State {
Proto *rootproto; /* list of all prototypes */
Closure *rootcl; /* list of all closures */
Hash *roottable; /* list of all tables */
- GlobalVar *rootglobal; /* list of global variables */
stringtable *string_root; /* array of hash tables for strings and udata */
+ Hash *gt; /* table for globals */
struct IM *IMtable; /* table for tag methods */
int last_tag; /* last used tag in IMtable */
struct Ref *refArray; /* locked objects */
diff --git a/lstring.c b/lstring.c
index 1dd4c9b9..3c9d0d8f 100644
--- a/lstring.c
+++ b/lstring.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstring.c,v 1.33 2000/03/10 14:38:10 roberto Exp roberto $
+** $Id: lstring.c,v 1.34 2000/03/10 18:37:44 roberto Exp roberto $
** String table (keeps all strings handled by Lua)
** See Copyright Notice in lua.h
*/
@@ -62,11 +62,13 @@ 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 */
- int h = p->hash&(newsize-1); /* new position */
- LUA_ASSERT(L, p->hash%newsize == (p->hash&(newsize-1)),
+ unsigned long h = (p->constindex == -1) ? IntPoint(p->u.d.value) :
+ p->u.s.hash;
+ int h1 = h&(newsize-1); /* new position */
+ LUA_ASSERT(L, h%newsize == (h&(newsize-1)),
"a&(x-1) == a%x, for x power of 2");
- p->nexthash = newhash[h]; /* chain it in new position */
- newhash[h] = p;
+ p->nexthash = newhash[h1]; /* chain it in new position */
+ newhash[h1] = p;
p = next;
}
}
@@ -76,32 +78,29 @@ void luaS_resize (lua_State *L, stringtable *tb, int newsize) {
}
-static TString *newone (lua_State *L, long l, unsigned long h) {
- TString *ts = (TString *)luaM_malloc(L,
- sizeof(TString)+l*sizeof(char));
+static TString *newone (lua_State *L, long l) {
+ TString *ts = (TString *)luaM_malloc(L, sizeof(TString)+l*sizeof(char));
ts->marked = 0;
ts->nexthash = NULL;
- ts->hash = h;
return ts;
}
static TString *newone_s (lua_State *L, const char *str,
long l, unsigned long h) {
- TString *ts = newone(L, l, h);
+ TString *ts = newone(L, l);
memcpy(ts->str, str, l);
ts->str[l] = 0; /* ending 0 */
- ts->u.s.gv = NULL; /* no global value */
ts->u.s.len = l;
+ ts->u.s.hash = h;
ts->constindex = 0;
L->nblocks += gcsizestring(L, l);
return ts;
}
-static TString *newone_u (lua_State *L, void *buff,
- int tag, unsigned long h) {
- TString *ts = newone(L, 0, h);
+static TString *newone_u (lua_State *L, void *buff, int tag) {
+ TString *ts = newone(L, 0);
ts->u.d.value = buff;
ts->u.d.tag = (tag == LUA_ANYTAG) ? 0 : tag;
ts->constindex = -1; /* tag -> this is a userdata */
@@ -141,7 +140,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, long l) {
** so two '&' operations would be highly correlated
*/
TString *luaS_createudata (lua_State *L, void *udata, int tag) {
- unsigned long h = IntPoint(L, udata);
+ unsigned long h = IntPoint(udata);
stringtable *tb = &L->string_root[(h%NUM_HASHUDATA)+NUM_HASHSTR];
int h1 = h&(tb->size-1);
TString *ts;
@@ -150,7 +149,7 @@ TString *luaS_createudata (lua_State *L, void *udata, int tag) {
return ts;
}
/* not found */
- ts = newone_u(L, udata, tag, h);
+ ts = newone_u(L, udata, tag);
newentry(L, tb, ts, h1);
return ts;
}
@@ -168,38 +167,8 @@ TString *luaS_newfixed (lua_State *L, const char *str) {
void luaS_free (lua_State *L, TString *t) {
- if (t->constindex == -1) /* is userdata? */
- L->nblocks -= gcsizeudata;
- else { /* is string */
- L->nblocks -= gcsizestring(L, t->u.s.len);
- luaM_free(L, t->u.s.gv);
- }
+ L->nblocks -= (t->constindex == -1) ? gcsizeudata :
+ gcsizestring(L, t->u.s.len);
luaM_free(L, t);
}
-
-GlobalVar *luaS_assertglobal (lua_State *L, TString *ts) {
- GlobalVar *gv = ts->u.s.gv;
- if (!gv) { /* no global value yet? */
- gv = luaM_new(L, GlobalVar);
- gv->value.ttype = TAG_NIL; /* initial value */
- gv->name = ts;
- gv->next = L->rootglobal; /* chain in global list */
- L->rootglobal = gv;
- ts->u.s.gv = gv;
- }
- return gv;
-}
-
-
-GlobalVar *luaS_assertglobalbyname (lua_State *L, const char *name) {
- return luaS_assertglobal(L, luaS_new(L, name));
-}
-
-
-int luaS_globaldefined (lua_State *L, const char *name) {
- TString *ts = luaS_new(L, name);
- return ts->u.s.gv && ts->u.s.gv->value.ttype != TAG_NIL;
-}
-
-
diff --git a/lstring.h b/lstring.h
index 80aa0b8f..8e307292 100644
--- a/lstring.h
+++ b/lstring.h
@@ -1,5 +1,5 @@
/*
-** $Id: lstring.h,v 1.17 2000/03/10 14:38:10 roberto Exp roberto $
+** $Id: lstring.h,v 1.18 2000/03/10 18:37:44 roberto Exp roberto $
** String table (keep all strings handled by Lua)
** See Copyright Notice in lua.h
*/
@@ -18,7 +18,7 @@
/*
-** any taggedstring with mark>=FIXMARK is never collected.
+** any TString with mark>=FIXMARK is never collected.
** Marks>=RESERVEDMARK are used to identify reserved words.
*/
#define FIXMARK 2
@@ -33,9 +33,6 @@ void luaS_free (lua_State *L, TString *ts);
TString *luaS_newlstr (lua_State *L, const char *str, long l);
TString *luaS_new (lua_State *L, const char *str);
TString *luaS_newfixed (lua_State *L, const char *str);
-GlobalVar *luaS_assertglobal (lua_State *L, TString *ts);
-GlobalVar *luaS_assertglobalbyname (lua_State *L, const char *name);
-int luaS_globaldefined (lua_State *L, const char *name);
#endif
diff --git a/ltable.c b/ltable.c
index cc3a64f1..fb8b3dfe 100644
--- a/ltable.c
+++ b/ltable.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltable.c,v 1.39 2000/03/31 16:28:45 roberto Exp roberto $
+** $Id: ltable.c,v 1.40 2000/04/25 16:55:09 roberto Exp roberto $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -24,6 +24,7 @@
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
+#include "lstring.h"
#include "ltable.h"
#include "lua.h"
@@ -46,14 +47,17 @@ Node *luaH_mainposition (const Hash *t, const TObject *key) {
case TAG_NUMBER:
h = (unsigned long)(long)nvalue(key);
break;
- case TAG_STRING: case TAG_USERDATA:
- h = tsvalue(key)->hash;
+ case TAG_STRING:
+ h = tsvalue(key)->u.s.hash;
+ break;
+ case TAG_USERDATA:
+ h = IntPoint(tsvalue(key));
break;
case TAG_TABLE:
- h = IntPoint(L, avalue(key));
+ h = IntPoint(avalue(key));
break;
case TAG_LCLOSURE: case TAG_CCLOSURE:
- h = IntPoint(L, clvalue(key));
+ h = IntPoint(clvalue(key));
break;
default:
return NULL; /* invalid key */
@@ -91,8 +95,8 @@ const TObject *luaH_getnum (const Hash *t, Number key) {
/* specialized version for strings */
-static const TObject *luaH_getstr (const Hash *t, TString *key) {
- Node *n = &t->node[key->hash&(t->size-1)];
+const TObject *luaH_getstr (const Hash *t, TString *key) {
+ Node *n = &t->node[key->u.s.hash&(t->size-1)];
do {
if (ttype(&n->key) == TAG_STRING && tsvalue(&n->key) == key)
return &n->val;
@@ -248,3 +252,7 @@ void luaH_setint (lua_State *L, Hash *t, int key, const TObject *val) {
luaH_set(L, t, &index, val);
}
+
+const TObject *luaH_getglobal (lua_State *L, const char *name) {
+ return luaH_getstr(L->gt, luaS_new(L, name));
+}
diff --git a/ltable.h b/ltable.h
index 9a5fe9a5..3d1f674a 100644
--- a/ltable.h
+++ b/ltable.h
@@ -1,5 +1,5 @@
/*
-** $Id: ltable.h,v 1.18 1999/12/07 12:05:34 roberto Exp roberto $
+** $Id: ltable.h,v 1.19 2000/04/25 16:55:09 roberto Exp roberto $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -19,11 +19,13 @@
Hash *luaH_new (lua_State *L, int nhash);
void luaH_free (lua_State *L, Hash *t);
const TObject *luaH_get (lua_State *L, const Hash *t, const TObject *key);
+const TObject *luaH_getnum (const Hash *t, Number key);
+const TObject *luaH_getstr (const Hash *t, TString *key);
void luaH_set (lua_State *L, Hash *t, const TObject *key, const TObject *val);
int luaH_pos (lua_State *L, const Hash *t, const TObject *r);
void luaH_setint (lua_State *L, Hash *t, int key, const TObject *val);
-const TObject *luaH_getnum (const Hash *t, Number key);
unsigned long luaH_hash (lua_State *L, const TObject *key);
+const TObject *luaH_getglobal (lua_State *L, const char *name);
/* exported only for debugging */
Node *luaH_mainposition (const Hash *t, const TObject *key);
diff --git a/ltests.c b/ltests.c
index 5ce089b9..03baa6e6 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltests.c,v 1.15 2000/04/13 16:51:01 roberto Exp roberto $
+** $Id: ltests.c,v 1.16 2000/04/14 17:46:15 roberto Exp roberto $
** Internal Module for Debugging of the Lua Implementation
** See Copyright Notice in lua.h
*/
@@ -167,7 +167,7 @@ static void hash_query (lua_State *L) {
lua_Object o = luaL_nonnullarg(L, 1);
if (lua_getparam(L, 2) == LUA_NOOBJECT) {
luaL_arg_check(L, ttype(o) == TAG_STRING, 1, "string expected");
- lua_pushnumber(L, tsvalue(o)->hash);
+ lua_pushnumber(L, tsvalue(o)->u.s.hash);
}
else {
const Hash *t = avalue(luaL_tablearg(L, 2));
@@ -334,9 +334,6 @@ static void testC (lua_State *L) {
else if EQ("type") {
lua_pushstring(L, lua_type(L, reg[getreg(L, &pc)]));
}
- else if EQ("nextvar") {
- lua_pushstring(L, lua_nextvar(L, lua_getstring(L, reg[getreg(L, &pc)])));
- }
else if EQ("next") {
int n = getreg(L, &pc);
n = lua_next(L, reg[n], (int)lua_getnumber(L, reg[getreg(L, &pc)]));
diff --git a/lua.h b/lua.h
index 23f5e472..58d5b27d 100644
--- a/lua.h
+++ b/lua.h
@@ -1,5 +1,5 @@
/*
-** $Id: lua.h,v 1.47 2000/04/14 17:48:20 roberto Exp roberto $
+** $Id: lua.h,v 1.48 2000/04/17 19:23:12 roberto Exp roberto $
** Lua - An Extensible Extension Language
** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
** e-mail: lua@tecgraf.puc-rio.br
@@ -54,6 +54,9 @@ int lua_callfunction (lua_State *L, lua_Object f);
void lua_beginblock (lua_State *L);
void lua_endblock (lua_State *L);
+void lua_pushglobaltable (lua_State *L);
+void lua_setglobaltable (lua_State *L, lua_Object newtable);
+
lua_Object lua_lua2C (lua_State *L, int number);
#define lua_getparam lua_lua2C
#define lua_getresult lua_lua2C
@@ -88,8 +91,8 @@ void lua_pushobject (lua_State *L, lua_Object obj);
lua_Object lua_pop (lua_State *L);
lua_Object lua_getglobal (lua_State *L, const char *name);
-lua_Object lua_rawgetglobal (lua_State *L, const char *name);
void lua_setglobal (lua_State *L, const char *name); /* In: value */
+lua_Object lua_rawgetglobal (lua_State *L, const char *name);
void lua_rawsetglobal (lua_State *L, const char *name);/* In: value */
void lua_settable (lua_State *L); /* In: table, index, value */
@@ -99,7 +102,6 @@ lua_Object lua_rawgettable (lua_State *L); /* In: table, index */
int lua_tag (lua_State *L, lua_Object obj);
-const char *lua_nextvar (lua_State *L, const char *varname); /* Out: value */
int lua_next (lua_State *L, lua_Object o, int i);
/* Out: ref, value */
@@ -167,6 +169,8 @@ extern lua_State *lua_state;
#define lua_callfunction(f) (lua_callfunction)(lua_state, f)
#define lua_beginblock() (lua_beginblock)(lua_state)
#define lua_endblock() (lua_endblock)(lua_state)
+#define lua_pushglobaltable() (lua_pushglobaltable)(lua_state)
+#define lua_setglobaltable(t) (lua_setglobaltable)(lua_state, t)
#define lua_lua2C(number) (lua_lua2C)(lua_state, number)
#define lua_type(obj) (lua_type)(lua_state, obj)
#define lua_isnil(obj) (lua_isnil)(lua_state, obj)
@@ -190,15 +194,14 @@ extern lua_State *lua_state;
#define lua_pushobject(obj) (lua_pushobject)(lua_state, obj)
#define lua_pop() (lua_pop)(lua_state)
#define lua_getglobal(name) (lua_getglobal)(lua_state, name)
-#define lua_rawgetglobal(name) (lua_rawgetglobal)(lua_state, name)
#define lua_setglobal(name) (lua_setglobal)(lua_state, name)
+#define lua_rawgetglobal(name) (lua_rawgetglobal)(lua_state, name)
#define lua_rawsetglobal(name) (lua_rawsetglobal)(lua_state, name)
#define lua_settable() (lua_settable)(lua_state)
#define lua_rawsettable() (lua_rawsettable)(lua_state)
#define lua_gettable() (lua_gettable)(lua_state)
#define lua_rawgettable() (lua_rawgettable)(lua_state)
#define lua_tag(obj) (lua_tag)(lua_state, obj)
-#define lua_nextvar(varname) (lua_nextvar)(lua_state, varname)
#define lua_next(o,i) (lua_next)(lua_state, o,i)
#define lua_ref(lock) (lua_ref)(lua_state, lock)
#define lua_getref(ref) (lua_getref)(lua_state, ref)
diff --git a/lundump.c b/lundump.c
index f9d90168..11ada16d 100644
--- a/lundump.c
+++ b/lundump.c
@@ -1,5 +1,5 @@
/*
-** $Id: lundump.c,v 1.28 2000/04/24 19:32:58 lhf Exp $
+** $Id: lundump.c,v 1.20 2000/04/25 16:44:31 roberto Exp roberto $
** load bytecodes from files
** See Copyright Notice in lua.h
*/
@@ -155,8 +155,7 @@ static void LoadConstants (lua_State* L, Proto* tf, ZIO* Z, int native)
for (i=0; i<n; i++)
{
TString* s=LoadString(L,Z);
- int isglobal=LoadByte(L,Z);
- if (isglobal) luaS_assertglobal(L,s);
+ LoadByte(L,Z);
tf->kstr[i]=s;
}
}
diff --git a/lvm.c b/lvm.c
index 23f59032..9b0ea0c8 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
/*
-** $Id: lvm.c,v 1.103 2000/04/14 17:45:25 roberto Exp roberto $
+** $Id: lvm.c,v 1.104 2000/04/19 13:36:25 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -164,18 +164,8 @@ void luaV_settable (lua_State *L, StkId t, StkId top) {
}
-void luaV_rawsettable (lua_State *L, StkId t) {
- if (ttype(t) != TAG_TABLE)
- lua_error(L, "indexed expression not a table");
- else {
- luaH_set(L, avalue(t), t+1, L->top-1);
- L->top -= 3;
- }
-}
-
-
-void luaV_getglobal (lua_State *L, GlobalVar *gv, StkId top) {
- const TObject *value = &gv->value;
+void luaV_getglobal (lua_State *L, TString *s, StkId top) {
+ const TObject *value = luaH_getstr(L->gt, s);
TObject *im = luaT_getimbyObj(L, value, IM_GETGLOBAL);
if (ttype(im) == TAG_NIL) /* is there a tag method? */
*top = *value; /* default behavior */
@@ -183,7 +173,7 @@ void luaV_getglobal (lua_State *L, GlobalVar *gv, StkId top) {
luaD_checkstack(L, 3);
*top = *im;
ttype(top+1) = TAG_STRING;
- tsvalue(top+1) = gv->name; /* global name */
+ tsvalue(top+1) = s; /* global name */
*(top+2) = *value;
L->top = top+3;
luaD_call(L, top, 1);
@@ -191,17 +181,25 @@ void luaV_getglobal (lua_State *L, GlobalVar *gv, StkId top) {
}
-void luaV_setglobal (lua_State *L, GlobalVar *gv, StkId top) {
- const TObject *oldvalue = &gv->value;
+void luaV_setglobal (lua_State *L, TString *s, StkId top) {
+ const TObject *oldvalue = luaH_getstr(L->gt, s);
const TObject *im = luaT_getimbyObj(L, oldvalue, IM_SETGLOBAL);
- if (ttype(im) == TAG_NIL) /* is there a tag method? */
- gv->value = *(top-1);
+ if (ttype(im) == TAG_NIL) { /* is there a tag method? */
+ if (oldvalue != &luaO_nilobject)
+ *oldvalue = *(top-1);
+ else {
+ TObject key;
+ ttype(&key) = TAG_STRING;
+ tsvalue(&key) = s;
+ luaH_set(L, L->gt, &key, top-1);
+ }
+ }
else {
luaD_checkstack(L, 3);
*(top+2) = *(top-1); /* new value */
*(top+1) = *oldvalue;
ttype(top) = TAG_STRING;
- tsvalue(top) = gv->name;
+ tsvalue(top) = s;
*(top-1) = *im;
L->top = top+3;
luaD_call(L, top-1, 0);
@@ -415,7 +413,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
break;
case OP_GETGLOBAL:
- luaV_getglobal(L, kstr[GETARG_U(i)]->u.s.gv, top);
+ luaV_getglobal(L, kstr[GETARG_U(i)], top);
top++;
break;
@@ -460,7 +458,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
break;
case OP_SETGLOBAL:
- luaV_setglobal(L, kstr[GETARG_U(i)]->u.s.gv, top);
+ luaV_setglobal(L, kstr[GETARG_U(i)], top);
top--;
break;
diff --git a/lvm.h b/lvm.h
index c3b2b6cc..ae57346b 100644
--- a/lvm.h
+++ b/lvm.h
@@ -1,5 +1,5 @@
/*
-** $Id: lvm.h,v 1.20 2000/03/29 20:19:20 roberto Exp roberto $
+** $Id: lvm.h,v 1.21 2000/04/19 13:36:25 roberto Exp roberto $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -23,9 +23,8 @@ int luaV_tostring (lua_State *L, TObject *obj);
void luaV_setn (lua_State *L, Hash *t, int val);
void luaV_gettable (lua_State *L, StkId top);
void luaV_settable (lua_State *L, StkId t, StkId top);
-void luaV_rawsettable (lua_State *L, StkId t);
-void luaV_getglobal (lua_State *L, GlobalVar *gv, StkId top);
-void luaV_setglobal (lua_State *L, GlobalVar *gv, StkId top);
+void luaV_getglobal (lua_State *L, TString *s, StkId top);
+void luaV_setglobal (lua_State *L, TString *s, StkId top);
StkId luaV_execute (lua_State *L, const Closure *cl, StkId base);
void luaV_Cclosure (lua_State *L, lua_CFunction c, int nelems);
void luaV_Lclosure (lua_State *L, Proto *l, int nelems);