global variables are stored in a Lua table

This commit is contained in:
Roberto Ierusalimschy 2000-05-08 16:32:53 -03:00
parent 35a6ed2838
commit 11a7022067
21 changed files with 181 additions and 275 deletions

80
lapi.c
View File

@ -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 ** Lua API
** See Copyright Notice in lua.h ** 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. ** Get a parameter, returning the object handle or LUA_NOOBJECT on error.
** `number' must be 1 to get the first parameter. ** `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) { void lua_rawsettable (lua_State *L) {
luaA_checkCargs(L, 3); 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) { 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); 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) { void lua_setglobal (lua_State *L, const char *name) {
luaA_checkCargs(L, 1); luaA_checkCargs(L, 1);
luaV_setglobal(L, luaS_assertglobalbyname(L, name), L->top--); luaV_setglobal(L, luaS_new(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) { void lua_rawsetglobal (lua_State *L, const char *name) {
GlobalVar *gv = luaS_assertglobalbyname(L, name); TObject key;
luaA_checkCargs(L, 1); 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 luaA_next (lua_State *L, const Hash *t, int i) {
int tsize = t->size; int tsize = t->size;
for (; i<tsize; i++) { for (; i<tsize; i++) {

3
lapi.h
View File

@ -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 ** Auxiliary functions from Lua API
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -13,7 +13,6 @@
void luaA_checkCargs (lua_State *L, int nargs); void luaA_checkCargs (lua_State *L, int nargs);
void luaA_pushobject (lua_State *L, const TObject *o); 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); int luaA_next (lua_State *L, const Hash *t, int i);
lua_Object luaA_putluaObject (lua_State *L, const TObject *o); lua_Object luaA_putluaObject (lua_State *L, const TObject *o);
lua_Object luaA_putObjectOnTop (lua_State *L); lua_Object luaA_putObjectOnTop (lua_State *L);

View File

@ -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 ** Built-in functions
** See Copyright Notice in lua.h ** 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) { static Number getsize (const Hash *h) {
Number max = 0; Number max = 0;
int i = h->size; int i = h->size;
@ -191,21 +184,10 @@ void luaB_setglobal (lua_State *L) {
lua_setglobal(L, name); 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) { void luaB_getglobal (lua_State *L) {
lua_pushobject(L, lua_getglobal(L, luaL_check_string(L, 1))); 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) { void luaB_tag (lua_State *L) {
lua_pushnumber(L, lua_tag(L, luaL_nonnullarg(L, 1))); 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))); 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) { void luaB_rawgettable (lua_State *L) {
lua_pushobject(L, luaL_nonnullarg(L, 1)); lua_pushobject(L, luaL_nonnullarg(L, 1));
lua_pushobject(L, luaL_nonnullarg(L, 2)); 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) { void luaB_next (lua_State *L) {
const Hash *a = gettable(L, 1); const Hash *a = gettable(L, 1);
lua_Object k = lua_getparam(L, 2); 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) { void luaB_getn (lua_State *L) {
lua_pushnumber(L, getnarg(L, gettable(L, 1))); 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[] = { static const struct luaL_reg builtin_funcs[] = {
{"_ALERT", luaB__ALERT}, {"_ALERT", luaB__ALERT},
{"_ERRORMESSAGE", luaB__ERRORMESSAGE}, {"_ERRORMESSAGE", luaB__ERRORMESSAGE},
@ -621,13 +606,11 @@ static const struct luaL_reg builtin_funcs[] = {
{"error", luaB_error}, {"error", luaB_error},
{"getglobal", luaB_getglobal}, {"getglobal", luaB_getglobal},
{"gettagmethod", luaB_gettagmethod}, {"gettagmethod", luaB_gettagmethod},
{"globals", luaB_globals},
{"newtag", luaB_newtag}, {"newtag", luaB_newtag},
{"next", luaB_next}, {"next", luaB_next},
{"nextvar", luaB_nextvar},
{"print", luaB_print}, {"print", luaB_print},
{"rawgetglobal", luaB_rawgetglobal},
{"rawgettable", luaB_rawgettable}, {"rawgettable", luaB_rawgettable},
{"rawsetglobal", luaB_rawsetglobal},
{"rawsettable", luaB_rawsettable}, {"rawsettable", luaB_rawsettable},
{"setglobal", luaB_setglobal}, {"setglobal", luaB_setglobal},
{"settag", luaB_settag}, {"settag", luaB_settag},
@ -640,7 +623,6 @@ static const struct luaL_reg builtin_funcs[] = {
{"assert", luaB_assert}, {"assert", luaB_assert},
{"foreach", luaB_foreach}, {"foreach", luaB_foreach},
{"foreachi", luaB_foreachi}, {"foreachi", luaB_foreachi},
{"foreachvar", luaB_foreachvar},
{"getn", luaB_getn}, {"getn", luaB_getn},
{"sort", luaB_sort}, {"sort", luaB_sort},
{"tinsert", luaB_tinsert}, {"tinsert", luaB_tinsert},
@ -648,6 +630,7 @@ static const struct luaL_reg builtin_funcs[] = {
}; };
void luaB_predefine (lua_State *L) { void luaB_predefine (lua_State *L) {
/* pre-register mem error messages, to avoid loop when error arises */ /* pre-register mem error messages, to avoid loop when error arises */
luaS_newfixed(L, tableEM); luaS_newfixed(L, tableEM);
@ -658,5 +641,6 @@ void luaB_predefine (lua_State *L) {
#endif #endif
lua_pushstring(L, LUA_VERSION); lua_pushstring(L, LUA_VERSION);
lua_setglobal(L, "_VERSION"); lua_setglobal(L, "_VERSION");
deprecated_funcs(L);
} }

View File

@ -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 ** Built-in functions
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -20,17 +20,14 @@ void luaB_dostring (lua_State *L);
void luaB_error (lua_State *L); void luaB_error (lua_State *L);
void luaB_foreach (lua_State *L); void luaB_foreach (lua_State *L);
void luaB_foreachi (lua_State *L); void luaB_foreachi (lua_State *L);
void luaB_foreachvar (lua_State *L);
void luaB_getglobal (lua_State *L); void luaB_getglobal (lua_State *L);
void luaB_getn (lua_State *L); void luaB_getn (lua_State *L);
void luaB_gettagmethod (lua_State *L); void luaB_gettagmethod (lua_State *L);
void luaB_globals (lua_State *L);
void luaB_newtag (lua_State *L); void luaB_newtag (lua_State *L);
void luaB_next (lua_State *L); void luaB_next (lua_State *L);
void luaB_nextvar (lua_State *L);
void luaB_print (lua_State *L); void luaB_print (lua_State *L);
void luaB_rawgetglobal (lua_State *L);
void luaB_rawgettable (lua_State *L); void luaB_rawgettable (lua_State *L);
void luaB_rawsetglobal (lua_State *L);
void luaB_rawsettable (lua_State *L); void luaB_rawsettable (lua_State *L);
void luaB_setglobal (lua_State *L); void luaB_setglobal (lua_State *L);
void luaB_settag (lua_State *L); void luaB_settag (lua_State *L);

10
lcode.c
View File

@ -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 ** Code generator for Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -16,7 +16,6 @@
#include "lobject.h" #include "lobject.h"
#include "lopcodes.h" #include "lopcodes.h"
#include "lparser.h" #include "lparser.h"
#include "lstring.h"
void luaK_error (LexState *ls, const char *msg) { 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) { static int discharge (FuncState *fs, expdesc *var) {
switch (var->k) { switch (var->k) {
case VLOCAL: case VLOCAL:
@ -160,7 +154,6 @@ static int discharge (FuncState *fs, expdesc *var) {
break; break;
case VGLOBAL: case VGLOBAL:
luaK_code1(fs, OP_GETGLOBAL, var->u.index); luaK_code1(fs, OP_GETGLOBAL, var->u.index);
assertglobal(fs, var->u.index); /* make sure that there is a global */
break; break;
case VINDEXED: case VINDEXED:
luaK_code0(fs, OP_GETTABLE); luaK_code0(fs, OP_GETTABLE);
@ -190,7 +183,6 @@ void luaK_storevar (LexState *ls, const expdesc *var) {
break; break;
case VGLOBAL: case VGLOBAL:
luaK_code1(fs, OP_SETGLOBAL, var->u.index); luaK_code1(fs, OP_SETGLOBAL, var->u.index);
assertglobal(fs, var->u.index); /* make sure that there is a global */
break; break;
case VINDEXED: /* table is at top-3; pop 3 elements after operation */ case VINDEXED: /* table is at top-3; pop 3 elements after operation */
luaK_code2(fs, OP_SETTABLE, 3, 3); luaK_code2(fs, OP_SETTABLE, 3, 3);

View File

@ -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 ** Debug Interface
** See Copyright Notice in lua.h ** 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) { 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 */ /* try to find a name for given function */
setnormalized(L->top, f); /* to be used by `checkfunc' */ setnormalized(L->top, f); /* to be used by `checkfunc' */
for (g=L->rootglobal; g; g=g->next) { for (i=0; i<=g->size; i++) {
if (checkfunc(L, &g->value)) { if (checkfunc(L, val(node(g,i))) && ttype(key(node(g,i))) == TAG_STRING) {
ar->name = g->name->str; ar->name = tsvalue(key(node(g,i)))->str;
ar->namewhat = "global"; ar->namewhat = "global";
return; return;
} }

5
ldo.c
View File

@ -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 ** Stack and Call structure of Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -21,6 +21,7 @@
#include "lparser.h" #include "lparser.h"
#include "lstate.h" #include "lstate.h"
#include "lstring.h" #include "lstring.h"
#include "ltable.h"
#include "ltm.h" #include "ltm.h"
#include "lua.h" #include "lua.h"
#include "luadebug.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) { 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') { if (*luaO_typename(em) == 'f') {
*L->top = *em; *L->top = *em;
incr_top; incr_top;

31
lgc.c
View File

@ -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 ** Garbage Collector
** See Copyright Notice in lua.h ** 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) { static void travstack (lua_State *L) {
int i; int i;
for (i = (L->top-1)-L->stack; i>=0; i--) for (i = (L->top-1)-L->stack; i>=0; i--)
@ -173,20 +161,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'. ** collect all elements with `marked' < `limit'.
** with limit=1, that means all unmarked elements; ** with limit=1, that means all unmarked elements;
@ -196,7 +170,6 @@ static void collectstring (lua_State *L, int limit) {
TObject o; /* to call userdata `gc' tag method */ TObject o; /* to call userdata `gc' tag method */
int i; int i;
ttype(&o) = TAG_USERDATA; ttype(&o) = TAG_USERDATA;
clear_global_list(L, limit);
for (i=0; i<NUM_HASHS; i++) { /* for each hash table */ for (i=0; i<NUM_HASHS; i++) { /* for each hash table */
stringtable *tb = &L->string_root[i]; stringtable *tb = &L->string_root[i];
int j; int j;
@ -228,7 +201,7 @@ static void collectstring (lua_State *L, int limit) {
static void markall (lua_State *L) { static void markall (lua_State *L) {
travstack(L); /* mark stack objects */ 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 */ travlock(L); /* mark locked objects */
luaT_travtagmethods(L, markobject); /* mark tag methods */ luaT_travtagmethods(L, markobject); /* mark tag methods */
} }

11
llex.c
View File

@ -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 ** Lexical Analyzer
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -18,6 +18,7 @@
#include "lparser.h" #include "lparser.h"
#include "lstate.h" #include "lstate.h"
#include "lstring.h" #include "lstring.h"
#include "ltable.h"
#include "luadebug.h" #include "luadebug.h"
#include "lzio.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 int checkcond (lua_State *L, LexState *LS, const char *buff) {
static const char *const opts[] = {"nil", "1", NULL}; static const char *const opts[] = {"nil", "1", NULL};
int i = luaL_findstring(buff, opts); int i = luaL_findstring(buff, opts);
if (i >= 0) return i; if (i >= 0) return i;
else if (isalpha((unsigned char)buff[0]) || buff[0] == '_') else if (isalpha((unsigned char)buff[0]) || buff[0] == '_')
return luaS_globaldefined(L, buff); return globaldefined(L, buff);
else { else {
luaX_syntaxerror(LS, "invalid $if condition", buff); luaX_syntaxerror(LS, "invalid $if condition", buff);
return 0; /* to avoid warnings */ return 0; /* to avoid warnings */

View File

@ -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 ** Type definitions for Lua objects
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -85,20 +85,13 @@ typedef struct TObject {
} TObject; } TObject;
typedef struct GlobalVar {
TObject value;
struct GlobalVar *next;
struct TString *name;
} GlobalVar;
/* /*
** String headers for string table ** String headers for string table
*/ */
typedef struct TString { typedef struct TString {
union { union {
struct { /* for strings */ struct { /* for strings */
GlobalVar *gv; /* eventual global value with this name */ unsigned long hash;
long len; long len;
} s; } s;
struct { /* for userdata */ struct { /* for userdata */
@ -107,7 +100,6 @@ typedef struct TString {
} d; } d;
} u; } u;
struct TString *nexthash; /* chain for hash table */ struct TString *nexthash; /* chain for hash table */
unsigned long hash;
int constindex; /* hint to reuse constants (= -1 if this is a userdata) */ int constindex; /* hint to reuse constants (= -1 if this is a userdata) */
unsigned char marked; unsigned char marked;
char str[1]; /* variable length string!! must be the last field! */ char str[1]; /* variable length string!! must be the last field! */

View File

@ -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 ** Global State
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -18,6 +18,7 @@
#include "lref.h" #include "lref.h"
#include "lstate.h" #include "lstate.h"
#include "lstring.h" #include "lstring.h"
#include "ltable.h"
#include "ltm.h" #include "ltm.h"
@ -35,7 +36,6 @@ static lua_State *newstate_aux (int stacksize, int put_builtin) {
L->numCblocks = 0; L->numCblocks = 0;
L->rootproto = NULL; L->rootproto = NULL;
L->rootcl = NULL; L->rootcl = NULL;
L->rootglobal = NULL;
L->roottable = NULL; L->roottable = NULL;
L->IMtable = NULL; L->IMtable = NULL;
L->refArray = NULL; L->refArray = NULL;
@ -47,6 +47,7 @@ static lua_State *newstate_aux (int stacksize, int put_builtin) {
L->callhook = NULL; L->callhook = NULL;
L->linehook = NULL; L->linehook = NULL;
L->allowhooks = 1; L->allowhooks = 1;
L->gt = luaH_new(L, 10);
luaD_init(L, stacksize); luaD_init(L, stacksize);
luaS_init(L); luaS_init(L);
luaX_init(L); luaX_init(L);
@ -87,7 +88,6 @@ void lua_close (lua_State *L) {
luaC_collect(L, 1); /* collect all elements */ luaC_collect(L, 1); /* collect all elements */
LUA_ASSERT(L, L->rootproto == NULL, "list should be empty"); LUA_ASSERT(L, L->rootproto == NULL, "list should be empty");
LUA_ASSERT(L, L->rootcl == 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"); LUA_ASSERT(L, L->roottable == NULL, "list should be empty");
luaS_freeall(L); luaS_freeall(L);
luaM_free(L, L->stack); luaM_free(L, L->stack);

View File

@ -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 ** Global State
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -42,7 +42,7 @@ struct C_Lua_Stack {
typedef struct stringtable { typedef struct stringtable {
int size; int size;
int nuse; /* number of elements (including EMPTYs) */ int nuse; /* number of elements */
TString **hash; TString **hash;
} stringtable; } stringtable;
@ -66,8 +66,8 @@ struct lua_State {
Proto *rootproto; /* list of all prototypes */ Proto *rootproto; /* list of all prototypes */
Closure *rootcl; /* list of all closures */ Closure *rootcl; /* list of all closures */
Hash *roottable; /* list of all tables */ Hash *roottable; /* list of all tables */
GlobalVar *rootglobal; /* list of global variables */
stringtable *string_root; /* array of hash tables for strings and udata */ stringtable *string_root; /* array of hash tables for strings and udata */
Hash *gt; /* table for globals */
struct IM *IMtable; /* table for tag methods */ struct IM *IMtable; /* table for tag methods */
int last_tag; /* last used tag in IMtable */ int last_tag; /* last used tag in IMtable */
struct Ref *refArray; /* locked objects */ struct Ref *refArray; /* locked objects */

View File

@ -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) ** String table (keeps all strings handled by Lua)
** See Copyright Notice in lua.h ** 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]; TString *p = tb->hash[i];
while (p) { /* for each node in the list */ while (p) { /* for each node in the list */
TString *next = p->nexthash; /* save next */ TString *next = p->nexthash; /* save next */
int h = p->hash&(newsize-1); /* new position */ unsigned long h = (p->constindex == -1) ? IntPoint(p->u.d.value) :
LUA_ASSERT(L, p->hash%newsize == (p->hash&(newsize-1)), 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"); "a&(x-1) == a%x, for x power of 2");
p->nexthash = newhash[h]; /* chain it in new position */ p->nexthash = newhash[h1]; /* chain it in new position */
newhash[h] = p; newhash[h1] = p;
p = next; 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) { static TString *newone (lua_State *L, long l) {
TString *ts = (TString *)luaM_malloc(L, TString *ts = (TString *)luaM_malloc(L, sizeof(TString)+l*sizeof(char));
sizeof(TString)+l*sizeof(char));
ts->marked = 0; ts->marked = 0;
ts->nexthash = NULL; ts->nexthash = NULL;
ts->hash = h;
return ts; return ts;
} }
static TString *newone_s (lua_State *L, const char *str, static TString *newone_s (lua_State *L, const char *str,
long l, unsigned long h) { long l, unsigned long h) {
TString *ts = newone(L, l, h); TString *ts = newone(L, l);
memcpy(ts->str, str, l); memcpy(ts->str, str, l);
ts->str[l] = 0; /* ending 0 */ ts->str[l] = 0; /* ending 0 */
ts->u.s.gv = NULL; /* no global value */
ts->u.s.len = l; ts->u.s.len = l;
ts->u.s.hash = h;
ts->constindex = 0; ts->constindex = 0;
L->nblocks += gcsizestring(L, l); L->nblocks += gcsizestring(L, l);
return ts; return ts;
} }
static TString *newone_u (lua_State *L, void *buff, static TString *newone_u (lua_State *L, void *buff, int tag) {
int tag, unsigned long h) { TString *ts = newone(L, 0);
TString *ts = newone(L, 0, h);
ts->u.d.value = buff; ts->u.d.value = buff;
ts->u.d.tag = (tag == LUA_ANYTAG) ? 0 : tag; ts->u.d.tag = (tag == LUA_ANYTAG) ? 0 : tag;
ts->constindex = -1; /* tag -> this is a userdata */ 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 ** so two '&' operations would be highly correlated
*/ */
TString *luaS_createudata (lua_State *L, void *udata, int tag) { 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]; stringtable *tb = &L->string_root[(h%NUM_HASHUDATA)+NUM_HASHSTR];
int h1 = h&(tb->size-1); int h1 = h&(tb->size-1);
TString *ts; TString *ts;
@ -150,7 +149,7 @@ TString *luaS_createudata (lua_State *L, void *udata, int tag) {
return ts; return ts;
} }
/* not found */ /* not found */
ts = newone_u(L, udata, tag, h); ts = newone_u(L, udata, tag);
newentry(L, tb, ts, h1); newentry(L, tb, ts, h1);
return ts; return ts;
} }
@ -168,38 +167,8 @@ TString *luaS_newfixed (lua_State *L, const char *str) {
void luaS_free (lua_State *L, TString *t) { void luaS_free (lua_State *L, TString *t) {
if (t->constindex == -1) /* is userdata? */ L->nblocks -= (t->constindex == -1) ? gcsizeudata :
L->nblocks -= gcsizeudata; gcsizestring(L, t->u.s.len);
else { /* is string */
L->nblocks -= gcsizestring(L, t->u.s.len);
luaM_free(L, t->u.s.gv);
}
luaM_free(L, t); 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;
}

View File

@ -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) ** String table (keep all strings handled by Lua)
** See Copyright Notice in lua.h ** 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. ** Marks>=RESERVEDMARK are used to identify reserved words.
*/ */
#define FIXMARK 2 #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_newlstr (lua_State *L, const char *str, long l);
TString *luaS_new (lua_State *L, const char *str); TString *luaS_new (lua_State *L, const char *str);
TString *luaS_newfixed (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 #endif

View File

@ -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) ** Lua tables (hash)
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -24,6 +24,7 @@
#include "lmem.h" #include "lmem.h"
#include "lobject.h" #include "lobject.h"
#include "lstate.h" #include "lstate.h"
#include "lstring.h"
#include "ltable.h" #include "ltable.h"
#include "lua.h" #include "lua.h"
@ -46,14 +47,17 @@ Node *luaH_mainposition (const Hash *t, const TObject *key) {
case TAG_NUMBER: case TAG_NUMBER:
h = (unsigned long)(long)nvalue(key); h = (unsigned long)(long)nvalue(key);
break; break;
case TAG_STRING: case TAG_USERDATA: case TAG_STRING:
h = tsvalue(key)->hash; h = tsvalue(key)->u.s.hash;
break;
case TAG_USERDATA:
h = IntPoint(tsvalue(key));
break; break;
case TAG_TABLE: case TAG_TABLE:
h = IntPoint(L, avalue(key)); h = IntPoint(avalue(key));
break; break;
case TAG_LCLOSURE: case TAG_CCLOSURE: case TAG_LCLOSURE: case TAG_CCLOSURE:
h = IntPoint(L, clvalue(key)); h = IntPoint(clvalue(key));
break; break;
default: default:
return NULL; /* invalid key */ return NULL; /* invalid key */
@ -91,8 +95,8 @@ const TObject *luaH_getnum (const Hash *t, Number key) {
/* specialized version for strings */ /* specialized version for strings */
static const TObject *luaH_getstr (const Hash *t, TString *key) { const TObject *luaH_getstr (const Hash *t, TString *key) {
Node *n = &t->node[key->hash&(t->size-1)]; Node *n = &t->node[key->u.s.hash&(t->size-1)];
do { do {
if (ttype(&n->key) == TAG_STRING && tsvalue(&n->key) == key) if (ttype(&n->key) == TAG_STRING && tsvalue(&n->key) == key)
return &n->val; 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); 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));
}

View File

@ -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) ** Lua tables (hash)
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -19,11 +19,13 @@
Hash *luaH_new (lua_State *L, int nhash); Hash *luaH_new (lua_State *L, int nhash);
void luaH_free (lua_State *L, Hash *t); void luaH_free (lua_State *L, Hash *t);
const TObject *luaH_get (lua_State *L, const Hash *t, const TObject *key); 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); 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); 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); 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); unsigned long luaH_hash (lua_State *L, const TObject *key);
const TObject *luaH_getglobal (lua_State *L, const char *name);
/* exported only for debugging */ /* exported only for debugging */
Node *luaH_mainposition (const Hash *t, const TObject *key); Node *luaH_mainposition (const Hash *t, const TObject *key);

View File

@ -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 ** Internal Module for Debugging of the Lua Implementation
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -167,7 +167,7 @@ static void hash_query (lua_State *L) {
lua_Object o = luaL_nonnullarg(L, 1); lua_Object o = luaL_nonnullarg(L, 1);
if (lua_getparam(L, 2) == LUA_NOOBJECT) { if (lua_getparam(L, 2) == LUA_NOOBJECT) {
luaL_arg_check(L, ttype(o) == TAG_STRING, 1, "string expected"); 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 { else {
const Hash *t = avalue(luaL_tablearg(L, 2)); const Hash *t = avalue(luaL_tablearg(L, 2));
@ -334,9 +334,6 @@ static void testC (lua_State *L) {
else if EQ("type") { else if EQ("type") {
lua_pushstring(L, lua_type(L, reg[getreg(L, &pc)])); 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") { else if EQ("next") {
int n = getreg(L, &pc); int n = getreg(L, &pc);
n = lua_next(L, reg[n], (int)lua_getnumber(L, reg[getreg(L, &pc)])); n = lua_next(L, reg[n], (int)lua_getnumber(L, reg[getreg(L, &pc)]));

13
lua.h
View File

@ -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 ** Lua - An Extensible Extension Language
** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil ** TeCGraf: Grupo de Tecnologia em Computacao Grafica, PUC-Rio, Brazil
** e-mail: lua@tecgraf.puc-rio.br ** 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_beginblock (lua_State *L);
void lua_endblock (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); lua_Object lua_lua2C (lua_State *L, int number);
#define lua_getparam lua_lua2C #define lua_getparam lua_lua2C
#define lua_getresult 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_pop (lua_State *L);
lua_Object lua_getglobal (lua_State *L, const char *name); 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 */ 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_rawsetglobal (lua_State *L, const char *name);/* In: value */
void lua_settable (lua_State *L); /* In: table, index, 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); 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); int lua_next (lua_State *L, lua_Object o, int i);
/* Out: ref, value */ /* Out: ref, value */
@ -167,6 +169,8 @@ extern lua_State *lua_state;
#define lua_callfunction(f) (lua_callfunction)(lua_state, f) #define lua_callfunction(f) (lua_callfunction)(lua_state, f)
#define lua_beginblock() (lua_beginblock)(lua_state) #define lua_beginblock() (lua_beginblock)(lua_state)
#define lua_endblock() (lua_endblock)(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_lua2C(number) (lua_lua2C)(lua_state, number)
#define lua_type(obj) (lua_type)(lua_state, obj) #define lua_type(obj) (lua_type)(lua_state, obj)
#define lua_isnil(obj) (lua_isnil)(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_pushobject(obj) (lua_pushobject)(lua_state, obj)
#define lua_pop() (lua_pop)(lua_state) #define lua_pop() (lua_pop)(lua_state)
#define lua_getglobal(name) (lua_getglobal)(lua_state, name) #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_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_rawsetglobal(name) (lua_rawsetglobal)(lua_state, name)
#define lua_settable() (lua_settable)(lua_state) #define lua_settable() (lua_settable)(lua_state)
#define lua_rawsettable() (lua_rawsettable)(lua_state) #define lua_rawsettable() (lua_rawsettable)(lua_state)
#define lua_gettable() (lua_gettable)(lua_state) #define lua_gettable() (lua_gettable)(lua_state)
#define lua_rawgettable() (lua_rawgettable)(lua_state) #define lua_rawgettable() (lua_rawgettable)(lua_state)
#define lua_tag(obj) (lua_tag)(lua_state, obj) #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_next(o,i) (lua_next)(lua_state, o,i)
#define lua_ref(lock) (lua_ref)(lua_state, lock) #define lua_ref(lock) (lua_ref)(lua_state, lock)
#define lua_getref(ref) (lua_getref)(lua_state, ref) #define lua_getref(ref) (lua_getref)(lua_state, ref)

View File

@ -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 ** load bytecodes from files
** See Copyright Notice in lua.h ** 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++) for (i=0; i<n; i++)
{ {
TString* s=LoadString(L,Z); TString* s=LoadString(L,Z);
int isglobal=LoadByte(L,Z); LoadByte(L,Z);
if (isglobal) luaS_assertglobal(L,s);
tf->kstr[i]=s; tf->kstr[i]=s;
} }
} }

40
lvm.c
View File

@ -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 ** Lua virtual machine
** See Copyright Notice in lua.h ** 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) { void luaV_getglobal (lua_State *L, TString *s, StkId top) {
if (ttype(t) != TAG_TABLE) const TObject *value = luaH_getstr(L->gt, s);
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;
TObject *im = luaT_getimbyObj(L, value, IM_GETGLOBAL); TObject *im = luaT_getimbyObj(L, value, IM_GETGLOBAL);
if (ttype(im) == TAG_NIL) /* is there a tag method? */ if (ttype(im) == TAG_NIL) /* is there a tag method? */
*top = *value; /* default behavior */ *top = *value; /* default behavior */
@ -183,7 +173,7 @@ void luaV_getglobal (lua_State *L, GlobalVar *gv, StkId top) {
luaD_checkstack(L, 3); luaD_checkstack(L, 3);
*top = *im; *top = *im;
ttype(top+1) = TAG_STRING; ttype(top+1) = TAG_STRING;
tsvalue(top+1) = gv->name; /* global name */ tsvalue(top+1) = s; /* global name */
*(top+2) = *value; *(top+2) = *value;
L->top = top+3; L->top = top+3;
luaD_call(L, top, 1); 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) { void luaV_setglobal (lua_State *L, TString *s, StkId top) {
const TObject *oldvalue = &gv->value; const TObject *oldvalue = luaH_getstr(L->gt, s);
const TObject *im = luaT_getimbyObj(L, oldvalue, IM_SETGLOBAL); const TObject *im = luaT_getimbyObj(L, oldvalue, IM_SETGLOBAL);
if (ttype(im) == TAG_NIL) /* is there a tag method? */ if (ttype(im) == TAG_NIL) { /* is there a tag method? */
gv->value = *(top-1); 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 { else {
luaD_checkstack(L, 3); luaD_checkstack(L, 3);
*(top+2) = *(top-1); /* new value */ *(top+2) = *(top-1); /* new value */
*(top+1) = *oldvalue; *(top+1) = *oldvalue;
ttype(top) = TAG_STRING; ttype(top) = TAG_STRING;
tsvalue(top) = gv->name; tsvalue(top) = s;
*(top-1) = *im; *(top-1) = *im;
L->top = top+3; L->top = top+3;
luaD_call(L, top-1, 0); luaD_call(L, top-1, 0);
@ -415,7 +413,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
break; break;
case OP_GETGLOBAL: case OP_GETGLOBAL:
luaV_getglobal(L, kstr[GETARG_U(i)]->u.s.gv, top); luaV_getglobal(L, kstr[GETARG_U(i)], top);
top++; top++;
break; break;
@ -460,7 +458,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
break; break;
case OP_SETGLOBAL: case OP_SETGLOBAL:
luaV_setglobal(L, kstr[GETARG_U(i)]->u.s.gv, top); luaV_setglobal(L, kstr[GETARG_U(i)], top);
top--; top--;
break; break;

7
lvm.h
View File

@ -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 ** Lua virtual machine
** See Copyright Notice in lua.h ** 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_setn (lua_State *L, Hash *t, int val);
void luaV_gettable (lua_State *L, StkId top); void luaV_gettable (lua_State *L, StkId top);
void luaV_settable (lua_State *L, StkId t, 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, TString *s, StkId top);
void luaV_getglobal (lua_State *L, GlobalVar *gv, StkId top); void luaV_setglobal (lua_State *L, TString *s, StkId top);
void luaV_setglobal (lua_State *L, GlobalVar *gv, StkId top);
StkId luaV_execute (lua_State *L, const Closure *cl, StkId base); StkId luaV_execute (lua_State *L, const Closure *cl, StkId base);
void luaV_Cclosure (lua_State *L, lua_CFunction c, int nelems); void luaV_Cclosure (lua_State *L, lua_CFunction c, int nelems);
void luaV_Lclosure (lua_State *L, Proto *l, int nelems); void luaV_Lclosure (lua_State *L, Proto *l, int nelems);