mirror of
https://github.com/lua/lua
synced 2025-04-08 14:02:56 +03:00
new implementation for global variable values (separated from strings)
This commit is contained in:
parent
80b39d83c3
commit
cde179b369
67
lapi.c
67
lapi.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lapi.c,v 1.53 1999/10/11 16:13:11 roberto Exp roberto $
|
** $Id: lapi.c,v 1.54 1999/10/14 19:13:31 roberto Exp roberto $
|
||||||
** Lua API
|
** Lua API
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -60,18 +60,6 @@ static const TObject *luaA_protovalue (const TObject *o) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaA_packresults (void) {
|
|
||||||
luaV_pack(L->Cstack.lua2C, L->Cstack.num, L->stack.top);
|
|
||||||
incr_top;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int luaA_passresults (void) {
|
|
||||||
L->Cstack.base = L->Cstack.lua2C; /* position of first result */
|
|
||||||
return L->Cstack.num;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void checkCparams (int nParams) {
|
static void checkCparams (int nParams) {
|
||||||
if (L->stack.top-L->stack.stack < L->Cstack.base+nParams)
|
if (L->stack.top-L->stack.stack < L->Cstack.base+nParams)
|
||||||
lua_error("API error - wrong number of arguments in C2lua stack");
|
lua_error("API error - wrong number of arguments in C2lua stack");
|
||||||
@ -191,28 +179,28 @@ lua_Object lua_createtable (void) {
|
|||||||
|
|
||||||
lua_Object lua_getglobal (const char *name) {
|
lua_Object lua_getglobal (const char *name) {
|
||||||
luaD_checkstack(2); /* may need that to call T.M. */
|
luaD_checkstack(2); /* may need that to call T.M. */
|
||||||
luaV_getglobal(luaS_new(name));
|
luaV_getglobal(luaS_assertglobalbyname(name));
|
||||||
return luaA_putObjectOnTop();
|
return luaA_putObjectOnTop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
lua_Object lua_rawgetglobal (const char *name) {
|
lua_Object lua_rawgetglobal (const char *name) {
|
||||||
TaggedString *ts = luaS_new(name);
|
GlobalVar *gv = luaS_assertglobalbyname(name);
|
||||||
return put_luaObject(&ts->u.s.globalval);
|
return put_luaObject(&gv->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void lua_setglobal (const char *name) {
|
void lua_setglobal (const char *name) {
|
||||||
checkCparams(1);
|
checkCparams(1);
|
||||||
luaD_checkstack(2); /* may need that to call T.M. */
|
luaD_checkstack(2); /* may need that to call T.M. */
|
||||||
luaV_setglobal(luaS_new(name));
|
luaV_setglobal(luaS_assertglobalbyname(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void lua_rawsetglobal (const char *name) {
|
void lua_rawsetglobal (const char *name) {
|
||||||
TaggedString *ts = luaS_new(name);
|
GlobalVar *gv = luaS_assertglobalbyname(name);
|
||||||
checkCparams(1);
|
checkCparams(1);
|
||||||
luaS_rawsetglobal(ts, --L->stack.top);
|
gv->value = *(--L->stack.top);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -274,7 +262,7 @@ long lua_strlen (lua_Object object) {
|
|||||||
void *lua_getuserdata (lua_Object object) {
|
void *lua_getuserdata (lua_Object object) {
|
||||||
if (object == LUA_NOOBJECT || ttype(Address(object)) != LUA_T_USERDATA)
|
if (object == LUA_NOOBJECT || ttype(Address(object)) != LUA_T_USERDATA)
|
||||||
return NULL;
|
return NULL;
|
||||||
else return tsvalue(Address(object))->u.d.v;
|
else return tsvalue(Address(object))->u.d.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_CFunction lua_getcfunction (lua_Object object) {
|
lua_CFunction lua_getcfunction (lua_Object object) {
|
||||||
@ -388,31 +376,32 @@ void lua_settag (int tag) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TaggedString *luaA_nextvar (TaggedString *g) {
|
GlobalVar *luaA_nextvar (TaggedString *ts) {
|
||||||
if (g == NULL)
|
GlobalVar *gv;
|
||||||
g = L->rootglobal; /* first variable */
|
if (ts == NULL)
|
||||||
|
gv = L->rootglobal; /* first variable */
|
||||||
else {
|
else {
|
||||||
/* check whether name is in global var list */
|
/* check whether name is in global var list */
|
||||||
luaL_arg_check(g != g->nextglobal, 1, "variable name expected");
|
luaL_arg_check(ts->u.s.gv, 1, "variable name expected");
|
||||||
g = g->nextglobal; /* get next */
|
gv = ts->u.s.gv->next; /* get next */
|
||||||
}
|
}
|
||||||
while (g && g->u.s.globalval.ttype == LUA_T_NIL) /* skip globals with nil */
|
while (gv && gv->value.ttype == LUA_T_NIL) /* skip globals with nil */
|
||||||
g = g->nextglobal;
|
gv = gv->next;
|
||||||
if (g) {
|
if (gv) {
|
||||||
ttype(L->stack.top) = LUA_T_STRING; tsvalue(L->stack.top) = g;
|
ttype(L->stack.top) = LUA_T_STRING; tsvalue(L->stack.top) = gv->name;
|
||||||
incr_top;
|
incr_top;
|
||||||
luaA_pushobject(&g->u.s.globalval);
|
luaA_pushobject(&gv->value);
|
||||||
}
|
}
|
||||||
return g;
|
return gv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char *lua_nextvar (const char *varname) {
|
const char *lua_nextvar (const char *varname) {
|
||||||
TaggedString *g = (varname == NULL) ? NULL : luaS_new(varname);
|
TaggedString *ts = (varname == NULL) ? NULL : luaS_new(varname);
|
||||||
g = luaA_nextvar(g);
|
GlobalVar *gv = luaA_nextvar(ts);
|
||||||
if (g) {
|
if (gv) {
|
||||||
top2LC(2);
|
top2LC(2);
|
||||||
return g->str;
|
return gv->name->str;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
top2LC(0);
|
top2LC(0);
|
||||||
@ -577,11 +566,11 @@ static int checkfunc (TObject *o) {
|
|||||||
|
|
||||||
const char *lua_getobjname (lua_Object o, const char **name) {
|
const char *lua_getobjname (lua_Object o, const char **name) {
|
||||||
/* try to find a name for given function */
|
/* try to find a name for given function */
|
||||||
TaggedString *g;
|
GlobalVar *g;
|
||||||
set_normalized(L->stack.top, Address(o)); /* to be accessed by "checkfunc" */
|
set_normalized(L->stack.top, Address(o)); /* to be accessed by "checkfunc" */
|
||||||
for (g=L->rootglobal; g; g=g->nextglobal) {
|
for (g=L->rootglobal; g; g=g->next) {
|
||||||
if (checkfunc(&g->u.s.globalval)) {
|
if (checkfunc(&g->value)) {
|
||||||
*name = g->str;
|
*name = g->name->str;
|
||||||
return "global";
|
return "global";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
6
lapi.h
6
lapi.h
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lapi.h,v 1.6 1999/09/20 14:57:29 roberto Exp roberto $
|
** $Id: lapi.h,v 1.7 1999/09/21 16:10:13 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
|
||||||
*/
|
*/
|
||||||
@ -14,9 +14,7 @@
|
|||||||
|
|
||||||
TObject *luaA_Address (lua_Object o);
|
TObject *luaA_Address (lua_Object o);
|
||||||
void luaA_pushobject (const TObject *o);
|
void luaA_pushobject (const TObject *o);
|
||||||
void luaA_packresults (void);
|
GlobalVar *luaA_nextvar (TaggedString *g);
|
||||||
int luaA_passresults (void);
|
|
||||||
TaggedString *luaA_nextvar (TaggedString *g);
|
|
||||||
int luaA_next (const Hash *t, int i);
|
int luaA_next (const Hash *t, int i);
|
||||||
lua_Object luaA_putObjectOnTop (void);
|
lua_Object luaA_putObjectOnTop (void);
|
||||||
|
|
||||||
|
61
lbuiltin.c
61
lbuiltin.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lbuiltin.c,v 1.68 1999/10/19 13:33:22 roberto Exp roberto $
|
** $Id: lbuiltin.c,v 1.69 1999/10/26 10:53:40 roberto Exp roberto $
|
||||||
** Built-in functions
|
** Built-in functions
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -35,10 +35,9 @@
|
|||||||
|
|
||||||
|
|
||||||
static void pushtagstring (TaggedString *s) {
|
static void pushtagstring (TaggedString *s) {
|
||||||
TObject o;
|
ttype(L->stack.top) = LUA_T_STRING;
|
||||||
o.ttype = LUA_T_STRING;
|
tsvalue(L->stack.top) = s;
|
||||||
o.value.ts = s;
|
incr_top;
|
||||||
luaA_pushobject(&o);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -107,7 +106,7 @@ static void error_message (void) {
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** If your system does not support "stdout", just remove this function.
|
** If your system does not support "stdout", you can just remove this function.
|
||||||
** If you need, you can define your own "print" function, following this
|
** If you need, you can define your own "print" function, following this
|
||||||
** model but changing "fputs" to put the strings at a proper place
|
** model but changing "fputs" to put the strings at a proper place
|
||||||
** (a console window or a log file, for instance).
|
** (a console window or a log file, for instance).
|
||||||
@ -264,22 +263,29 @@ static void luaB_type (void) {
|
|||||||
** =======================================================
|
** =======================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
static void passresults (void) {
|
||||||
|
L->Cstack.base = L->Cstack.lua2C; /* position of first result */
|
||||||
|
if (L->Cstack.num == 0)
|
||||||
|
lua_pushuserdata(NULL); /* at least one result to signal no errors */
|
||||||
|
}
|
||||||
|
|
||||||
static void luaB_dostring (void) {
|
static void luaB_dostring (void) {
|
||||||
long l;
|
long l;
|
||||||
const char *s = luaL_check_lstr(1, &l);
|
const char *s = luaL_check_lstr(1, &l);
|
||||||
if (*s == ID_CHUNK)
|
if (*s == ID_CHUNK)
|
||||||
lua_error("`dostring' cannot run pre-compiled code");
|
lua_error("`dostring' cannot run pre-compiled code");
|
||||||
if (lua_dobuffer(s, l, luaL_opt_string(2, s)) == 0)
|
if (lua_dobuffer(s, l, luaL_opt_string(2, s)) == 0)
|
||||||
if (luaA_passresults() == 0)
|
passresults();
|
||||||
lua_pushuserdata(NULL); /* at least one result to signal no errors */
|
/* else return no value */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void luaB_dofile (void) {
|
static void luaB_dofile (void) {
|
||||||
const char *fname = luaL_opt_string(1, NULL);
|
const char *fname = luaL_opt_string(1, NULL);
|
||||||
if (lua_dofile(fname) == 0)
|
if (lua_dofile(fname) == 0)
|
||||||
if (luaA_passresults() == 0)
|
passresults();
|
||||||
lua_pushuserdata(NULL); /* at least one result to signal no errors */
|
/* else return no value */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -312,10 +318,12 @@ static void luaB_call (void) {
|
|||||||
lua_error(NULL);
|
lua_error(NULL);
|
||||||
}
|
}
|
||||||
else { /* no errors */
|
else { /* no errors */
|
||||||
if (strchr(options, 'p'))
|
if (strchr(options, 'p')) { /* pack results? */
|
||||||
luaA_packresults();
|
luaV_pack(L->Cstack.lua2C, L->Cstack.num, L->stack.top);
|
||||||
|
incr_top;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
luaA_passresults();
|
L->Cstack.base = L->Cstack.lua2C; /* position of first result */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,7 +381,7 @@ static void luaB_tostring (void) {
|
|||||||
sprintf(buff, "function: %p", (void *)o->value.f);
|
sprintf(buff, "function: %p", (void *)o->value.f);
|
||||||
break;
|
break;
|
||||||
case LUA_T_USERDATA:
|
case LUA_T_USERDATA:
|
||||||
sprintf(buff, "userdata: %p", o->value.ts->u.d.v);
|
sprintf(buff, "userdata: %p", o->value.ts->u.d.value);
|
||||||
break;
|
break;
|
||||||
case LUA_T_NIL:
|
case LUA_T_NIL:
|
||||||
lua_pushstring("nil");
|
lua_pushstring("nil");
|
||||||
@ -449,23 +457,23 @@ static void luaB_foreach (void) {
|
|||||||
|
|
||||||
|
|
||||||
static void luaB_foreachvar (void) {
|
static void luaB_foreachvar (void) {
|
||||||
TaggedString *s;
|
GlobalVar *gv;
|
||||||
TObject f; /* see comment in 'foreachi' */
|
TObject f; /* see comment in 'foreachi' */
|
||||||
f = *luaA_Address(luaL_functionarg(1));
|
f = *luaA_Address(luaL_functionarg(1));
|
||||||
luaD_checkstack(4); /* for extra var name, f, var name, and globalval */
|
luaD_checkstack(4); /* for extra var name, f, var name, and globalval */
|
||||||
for (s = L->rootglobal; s; s = s->nextglobal) {
|
for (gv = L->rootglobal; gv; gv = gv->next) {
|
||||||
if (s->u.s.globalval.ttype != LUA_T_NIL) {
|
if (gv->value.ttype != LUA_T_NIL) {
|
||||||
pushtagstring(s); /* keep (extra) s on stack to avoid GC */
|
pushtagstring(gv->name); /* keep (extra) name on stack to avoid GC */
|
||||||
*(L->stack.top++) = f;
|
*(L->stack.top++) = f;
|
||||||
pushtagstring(s);
|
pushtagstring(gv->name);
|
||||||
*(L->stack.top++) = s->u.s.globalval;
|
*(L->stack.top++) = gv->value;
|
||||||
luaD_calln(2, 1);
|
luaD_calln(2, 1);
|
||||||
if (ttype(L->stack.top-1) != LUA_T_NIL) {
|
if (ttype(L->stack.top-1) != LUA_T_NIL) {
|
||||||
L->stack.top--;
|
L->stack.top--;
|
||||||
*(L->stack.top-1) = *L->stack.top; /* remove extra `s' */
|
*(L->stack.top-1) = *L->stack.top; /* remove extra name */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
L->stack.top-=2; /* remove result and extra `s' */
|
L->stack.top-=2; /* remove result and extra name */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -507,7 +515,8 @@ static void luaB_tremove (void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* {
|
/*
|
||||||
|
** {======================================================
|
||||||
** Quicksort
|
** Quicksort
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -593,11 +602,10 @@ static void luaB_sort (void) {
|
|||||||
lua_pushobject(t);
|
lua_pushobject(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* }}===================================================== */
|
/* }====================================================== */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/* }====================================================== */
|
||||||
** ====================================================== */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -605,6 +613,7 @@ static void luaB_sort (void) {
|
|||||||
/*
|
/*
|
||||||
** {======================================================
|
** {======================================================
|
||||||
** some DEBUG functions
|
** some DEBUG functions
|
||||||
|
** (for internal debugging of the Lua implementation)
|
||||||
** =======================================================
|
** =======================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
5
ldo.c
5
ldo.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ldo.c,v 1.49 1999/10/14 17:53:35 roberto Exp roberto $
|
** $Id: ldo.c,v 1.50 1999/10/14 19:46:57 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
|
||||||
*/
|
*/
|
||||||
@ -219,7 +219,7 @@ void luaD_calln (int nArgs, int nResults) {
|
|||||||
|
|
||||||
|
|
||||||
static void message (const char *s) {
|
static void message (const char *s) {
|
||||||
const TObject *em = &(luaS_new("_ERRORMESSAGE")->u.s.globalval);
|
const TObject *em = &(luaS_assertglobalbyname("_ERRORMESSAGE")->value);
|
||||||
if (ttype(em) == LUA_T_PROTO || ttype(em) == LUA_T_CPROTO ||
|
if (ttype(em) == LUA_T_PROTO || ttype(em) == LUA_T_CPROTO ||
|
||||||
ttype(em) == LUA_T_CLOSURE) {
|
ttype(em) == LUA_T_CLOSURE) {
|
||||||
*L->stack.top = *em;
|
*L->stack.top = *em;
|
||||||
@ -237,7 +237,6 @@ void lua_error (const char *s) {
|
|||||||
if (L->errorJmp)
|
if (L->errorJmp)
|
||||||
longjmp(L->errorJmp->b, 1);
|
longjmp(L->errorJmp->b, 1);
|
||||||
else {
|
else {
|
||||||
LUA_INTERNALERROR("exit!!");
|
|
||||||
message("exit(1). Unable to recover.\n");
|
message("exit(1). Unable to recover.\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
33
lgc.c
33
lgc.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lgc.c,v 1.28 1999/10/11 16:13:11 roberto Exp roberto $
|
** $Id: lgc.c,v 1.29 1999/10/14 19:13:31 roberto Exp roberto $
|
||||||
** Garbage Collector
|
** Garbage Collector
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -62,13 +62,13 @@ static void hashmark (Hash *h) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void globalmark (void) {
|
static void travglobal (void) {
|
||||||
TaggedString *g;
|
GlobalVar *gv;
|
||||||
for (g=L->rootglobal; g; g=g->nextglobal) {
|
for (gv=L->rootglobal; gv; gv=gv->next) {
|
||||||
LUA_ASSERT(g->constindex >= 0, "userdata in global list");
|
LUA_ASSERT(gv->name->u.s.gv == gv, "inconsistent global name");
|
||||||
if (g->u.s.globalval.ttype != LUA_T_NIL) {
|
if (gv->value.ttype != LUA_T_NIL) {
|
||||||
markobject(&g->u.s.globalval);
|
strmark(gv->name); /* cannot collect non nil global variables */
|
||||||
strmark(g); /* cannot collect non nil global variables */
|
markobject(&gv->value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -157,12 +157,16 @@ static void collecttable (void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** 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 (int limit) {
|
static void clear_global_list (int limit) {
|
||||||
TaggedString **p = &L->rootglobal;
|
GlobalVar **p = &L->rootglobal;
|
||||||
TaggedString *next;
|
GlobalVar *next;
|
||||||
while ((next = *p) != NULL) {
|
while ((next = *p) != NULL) {
|
||||||
if (next->marked >= limit) p = &next->nextglobal;
|
if (next->name->marked >= limit) p = &next->next;
|
||||||
else *p = next->nextglobal;
|
else *p = next->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,7 +230,7 @@ static void tableTM (void) {
|
|||||||
|
|
||||||
static void markall (void) {
|
static void markall (void) {
|
||||||
travstack(); /* mark stack objects */
|
travstack(); /* mark stack objects */
|
||||||
globalmark(); /* mark global variable values and names */
|
travglobal(); /* mark global variable values and names */
|
||||||
travlock(); /* mark locked objects */
|
travlock(); /* mark locked objects */
|
||||||
luaT_travtagmethods(markobject); /* mark tag methods */
|
luaT_travtagmethods(markobject); /* mark tag methods */
|
||||||
}
|
}
|
||||||
@ -239,8 +243,6 @@ void luaC_collect (int all) {
|
|||||||
collectstring(all?MAX_INT:1);
|
collectstring(all?MAX_INT:1);
|
||||||
collectproto();
|
collectproto();
|
||||||
collectclosure();
|
collectclosure();
|
||||||
if (!all)
|
|
||||||
luaD_gcIM(&luaO_nilobject); /* GC tag method for nil (signal end of GC) */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -249,6 +251,7 @@ long lua_collectgarbage (long limit) {
|
|||||||
markall();
|
markall();
|
||||||
luaR_invalidaterefs();
|
luaR_invalidaterefs();
|
||||||
luaC_collect(0);
|
luaC_collect(0);
|
||||||
|
luaD_gcIM(&luaO_nilobject); /* GC tag method for nil (signal end of GC) */
|
||||||
recovered = recovered - L->nblocks;
|
recovered = recovered - L->nblocks;
|
||||||
L->GCthreshold = (limit == 0) ? 2*L->nblocks : L->nblocks+limit;
|
L->GCthreshold = (limit == 0) ? 2*L->nblocks : L->nblocks+limit;
|
||||||
return recovered;
|
return recovered;
|
||||||
|
27
lobject.h
27
lobject.h
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lobject.h,v 1.33 1999/10/14 19:13:31 roberto Exp roberto $
|
** $Id: lobject.h,v 1.34 1999/10/19 13:33:22 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
|
||||||
*/
|
*/
|
||||||
@ -87,25 +87,30 @@ typedef struct TObject {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct GlobalVar {
|
||||||
|
TObject value;
|
||||||
|
struct GlobalVar *next;
|
||||||
|
struct TaggedString *name;
|
||||||
|
} GlobalVar;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** String headers for string table
|
** String headers for string table
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct TaggedString {
|
typedef struct TaggedString {
|
||||||
struct TaggedString *nexthash; /* chain hash table */
|
|
||||||
struct TaggedString *nextglobal; /* chain global variables */
|
|
||||||
unsigned long hash;
|
|
||||||
int constindex; /* hint to reuse constants (= -1 if this is a userdata) */
|
|
||||||
union {
|
union {
|
||||||
struct {
|
struct { /* for strings */
|
||||||
TObject globalval;
|
GlobalVar *gv; /* eventual global value with this name */
|
||||||
long len; /* if this is a string, here is its length */
|
long len;
|
||||||
} s;
|
} s;
|
||||||
struct {
|
struct { /* for userdata */
|
||||||
int tag;
|
int tag;
|
||||||
void *v; /* if this is a userdata, here is its value */
|
void *value;
|
||||||
} d;
|
} d;
|
||||||
} u;
|
} u;
|
||||||
|
struct TaggedString *nexthash; /* chain for hash table */
|
||||||
|
unsigned long hash;
|
||||||
|
int constindex; /* hint to reuse constants (= -1 if this is a userdata) */
|
||||||
unsigned char marked;
|
unsigned char marked;
|
||||||
char str[1]; /* \0 byte already reserved */
|
char str[1]; /* \0 byte already reserved */
|
||||||
} TaggedString;
|
} TaggedString;
|
||||||
|
11
lparser.c
11
lparser.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lparser.c,v 1.40 1999/09/02 13:13:22 roberto Exp roberto $
|
** $Id: lparser.c,v 1.41 1999/09/20 14:15:18 roberto Exp roberto $
|
||||||
** LL(1) Parser and code generator for Lua
|
** LL(1) Parser and code generator for Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -232,6 +232,13 @@ static void code_constant (LexState *ls, int c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void assertglobal (LexState *ls, int index) {
|
||||||
|
TObject *o = &ls->fs->f->consts[index];
|
||||||
|
LUA_ASSERT(ttype(o) == LUA_T_STRING, "global name is not a string");
|
||||||
|
luaS_assertglobal(tsvalue(o));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int next_constant (FuncState *fs) {
|
static int next_constant (FuncState *fs) {
|
||||||
TProtoFunc *f = fs->f;
|
TProtoFunc *f = fs->f;
|
||||||
luaM_growvector(f->consts, f->nconsts, 1, TObject, constantEM, MAX_ARG);
|
luaM_growvector(f->consts, f->nconsts, 1, TObject, constantEM, MAX_ARG);
|
||||||
@ -478,6 +485,7 @@ static void lua_pushvar (LexState *ls, vardesc *var) {
|
|||||||
break;
|
break;
|
||||||
case VGLOBAL:
|
case VGLOBAL:
|
||||||
code_oparg(ls, GETGLOBAL, var->info, 1);
|
code_oparg(ls, GETGLOBAL, var->info, 1);
|
||||||
|
assertglobal(ls, var->info); /* make sure that there is a global */
|
||||||
break;
|
break;
|
||||||
case VDOT:
|
case VDOT:
|
||||||
code_oparg(ls, GETDOTTED, var->info, 0);
|
code_oparg(ls, GETDOTTED, var->info, 0);
|
||||||
@ -501,6 +509,7 @@ static void storevar (LexState *ls, const vardesc *var) {
|
|||||||
break;
|
break;
|
||||||
case VGLOBAL:
|
case VGLOBAL:
|
||||||
code_oparg(ls, SETGLOBAL, var->info, -1);
|
code_oparg(ls, SETGLOBAL, var->info, -1);
|
||||||
|
assertglobal(ls, var->info); /* make sure that there is a global */
|
||||||
break;
|
break;
|
||||||
case VINDEXED:
|
case VINDEXED:
|
||||||
code_opcode(ls, SETTABLEPOP, -3);
|
code_opcode(ls, SETTABLEPOP, -3);
|
||||||
|
4
lstate.h
4
lstate.h
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lstate.h,v 1.19 1999/05/11 20:08:20 roberto Exp roberto $
|
** $Id: lstate.h,v 1.20 1999/10/04 17:51:04 roberto Exp roberto $
|
||||||
** Global State
|
** Global State
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -76,7 +76,7 @@ struct lua_State {
|
|||||||
TProtoFunc *rootproto; /* list of all prototypes */
|
TProtoFunc *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 */
|
||||||
TaggedString *rootglobal; /* list of strings with global values */
|
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 */
|
||||||
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 */
|
||||||
|
66
lstring.c
66
lstring.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lstring.c,v 1.24 1999/10/14 19:13:31 roberto Exp roberto $
|
** $Id: lstring.c,v 1.25 1999/10/19 13:33:22 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
|
||||||
*/
|
*/
|
||||||
@ -87,7 +87,6 @@ static TaggedString *newone (long l, unsigned long h) {
|
|||||||
sizeof(TaggedString)+l*sizeof(char));
|
sizeof(TaggedString)+l*sizeof(char));
|
||||||
ts->marked = 0;
|
ts->marked = 0;
|
||||||
ts->nexthash = NULL;
|
ts->nexthash = NULL;
|
||||||
ts->nextglobal = ts; /* signal it is not in global list */
|
|
||||||
ts->hash = h;
|
ts->hash = h;
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
@ -97,7 +96,7 @@ static TaggedString *newone_s (const char *str, long l, unsigned long h) {
|
|||||||
TaggedString *ts = newone(l, h);
|
TaggedString *ts = newone(l, h);
|
||||||
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.globalval.ttype = LUA_T_NIL; /* initialize global value */
|
ts->u.s.gv = NULL; /* no global value */
|
||||||
ts->u.s.len = l;
|
ts->u.s.len = l;
|
||||||
ts->constindex = 0;
|
ts->constindex = 0;
|
||||||
L->nblocks += gcsizestring(l);
|
L->nblocks += gcsizestring(l);
|
||||||
@ -107,7 +106,7 @@ static TaggedString *newone_s (const char *str, long l, unsigned long h) {
|
|||||||
|
|
||||||
static TaggedString *newone_u (void *buff, int tag, unsigned long h) {
|
static TaggedString *newone_u (void *buff, int tag, unsigned long h) {
|
||||||
TaggedString *ts = newone(0, h);
|
TaggedString *ts = newone(0, h);
|
||||||
ts->u.d.v = 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 */
|
||||||
L->nblocks++;
|
L->nblocks++;
|
||||||
@ -131,13 +130,15 @@ static void newentry (stringtable *tb, TaggedString *ts, int h) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static TaggedString *insert_s (const char *str, long l,
|
TaggedString *luaS_newlstr (const char *str, long l) {
|
||||||
stringtable *tb, unsigned long h) {
|
unsigned long h = hash_s(str, l);
|
||||||
|
stringtable *tb = &L->string_root[h%NUM_HASHSTR];
|
||||||
int h1 = h%tb->size;
|
int h1 = h%tb->size;
|
||||||
TaggedString *ts;
|
TaggedString *ts;
|
||||||
for (ts = tb->hash[h1]; ts; ts = ts->nexthash)
|
for (ts = tb->hash[h1]; ts; ts = ts->nexthash) {
|
||||||
if (ts->u.s.len == l && (memcmp(str, ts->str, l) == 0))
|
if (ts->u.s.len == l && (memcmp(str, ts->str, l) == 0))
|
||||||
return ts;
|
return ts;
|
||||||
|
}
|
||||||
/* not found */
|
/* not found */
|
||||||
ts = newone_s(str, l, h); /* create new entry */
|
ts = newone_s(str, l, h); /* create new entry */
|
||||||
newentry(tb, ts, h1); /* insert it on table */
|
newentry(tb, ts, h1); /* insert it on table */
|
||||||
@ -145,30 +146,22 @@ static TaggedString *insert_s (const char *str, long l,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static TaggedString *insert_u (void *buff, int tag, stringtable *tb) {
|
TaggedString *luaS_createudata (void *udata, int tag) {
|
||||||
unsigned long h = (IntPoint)buff;
|
unsigned long h = (IntPoint)udata;
|
||||||
|
stringtable *tb = &L->string_root[(h%NUM_HASHUDATA)+NUM_HASHSTR];
|
||||||
int h1 = h%tb->size;
|
int h1 = h%tb->size;
|
||||||
TaggedString *ts;
|
TaggedString *ts;
|
||||||
for (ts = tb->hash[h1]; ts; ts = ts->nexthash)
|
for (ts = tb->hash[h1]; ts; ts = ts->nexthash) {
|
||||||
if ((tag == ts->u.d.tag || tag == LUA_ANYTAG) && buff == ts->u.d.v)
|
if (udata == ts->u.d.value && (tag == ts->u.d.tag || tag == LUA_ANYTAG))
|
||||||
return ts;
|
return ts;
|
||||||
|
}
|
||||||
/* not found */
|
/* not found */
|
||||||
ts = newone_u(buff, tag, h);
|
ts = newone_u(udata, tag, h);
|
||||||
newentry(tb, ts, h1);
|
newentry(tb, ts, h1);
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TaggedString *luaS_createudata (void *udata, int tag) {
|
|
||||||
int t = ((IntPoint)udata%NUM_HASHUDATA)+NUM_HASHSTR;
|
|
||||||
return insert_u(udata, tag, &L->string_root[t]);
|
|
||||||
}
|
|
||||||
|
|
||||||
TaggedString *luaS_newlstr (const char *str, long l) {
|
|
||||||
unsigned long h = hash_s(str, l);
|
|
||||||
return insert_s(str, l, &L->string_root[h%NUM_HASHSTR], h);
|
|
||||||
}
|
|
||||||
|
|
||||||
TaggedString *luaS_new (const char *str) {
|
TaggedString *luaS_new (const char *str) {
|
||||||
return luaS_newlstr(str, strlen(str));
|
return luaS_newlstr(str, strlen(str));
|
||||||
}
|
}
|
||||||
@ -181,23 +174,38 @@ TaggedString *luaS_newfixedstring (const char *str) {
|
|||||||
|
|
||||||
|
|
||||||
void luaS_free (TaggedString *t) {
|
void luaS_free (TaggedString *t) {
|
||||||
L->nblocks -= (t->constindex == -1) ? 1 : gcsizestring(t->u.s.len);
|
if (t->constindex == -1) /* is userdata? */
|
||||||
|
L->nblocks--;
|
||||||
|
else { /* is string */
|
||||||
|
L->nblocks -= gcsizestring(t->u.s.len);
|
||||||
|
luaM_free(t->u.s.gv);
|
||||||
|
}
|
||||||
luaM_free(t);
|
luaM_free(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaS_rawsetglobal (TaggedString *ts, const TObject *newval) {
|
GlobalVar *luaS_assertglobal (TaggedString *ts) {
|
||||||
ts->u.s.globalval = *newval;
|
GlobalVar *gv = ts->u.s.gv;
|
||||||
if (ts->nextglobal == ts) { /* is not in list? */
|
if (!gv) { /* no global value yet? */
|
||||||
ts->nextglobal = L->rootglobal;
|
gv = luaM_new(GlobalVar);
|
||||||
L->rootglobal = ts;
|
gv->value.ttype = LUA_T_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 (const char *name) {
|
||||||
|
return luaS_assertglobal(luaS_new(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int luaS_globaldefined (const char *name) {
|
int luaS_globaldefined (const char *name) {
|
||||||
TaggedString *ts = luaS_new(name);
|
TaggedString *ts = luaS_new(name);
|
||||||
return ts->u.s.globalval.ttype != LUA_T_NIL;
|
return ts->u.s.gv && ts->u.s.gv->value.ttype != LUA_T_NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lstring.h,v 1.10 1999/10/11 16:13:11 roberto Exp roberto $
|
** $Id: lstring.h,v 1.11 1999/10/14 19:13:31 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
|
||||||
*/
|
*/
|
||||||
@ -33,7 +33,8 @@ void luaS_free (TaggedString *ts);
|
|||||||
TaggedString *luaS_newlstr (const char *str, long l);
|
TaggedString *luaS_newlstr (const char *str, long l);
|
||||||
TaggedString *luaS_new (const char *str);
|
TaggedString *luaS_new (const char *str);
|
||||||
TaggedString *luaS_newfixedstring (const char *str);
|
TaggedString *luaS_newfixedstring (const char *str);
|
||||||
void luaS_rawsetglobal (TaggedString *ts, const TObject *newval);
|
GlobalVar *luaS_assertglobal (TaggedString *ts);
|
||||||
|
GlobalVar *luaS_assertglobalbyname (const char *name);
|
||||||
int luaS_globaldefined (const char *name);
|
int luaS_globaldefined (const char *name);
|
||||||
|
|
||||||
|
|
||||||
|
20
lvm.c
20
lvm.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lvm.c,v 1.63 1999/10/14 19:13:31 roberto Exp roberto $
|
** $Id: lvm.c,v 1.64 1999/10/14 19:46:57 roberto Exp roberto $
|
||||||
** Lua virtual machine
|
** Lua virtual machine
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -167,9 +167,9 @@ void luaV_rawsettable (const TObject *t) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaV_getglobal (TaggedString *ts) {
|
void luaV_getglobal (GlobalVar *gv) {
|
||||||
/* WARNING: caller must assure stack space */
|
/* WARNING: caller must assure stack space */
|
||||||
const TObject *value = &ts->u.s.globalval;
|
const TObject *value = &gv->value;
|
||||||
switch (ttype(value)) {
|
switch (ttype(value)) {
|
||||||
/* only userdata, tables and nil can have getglobal tag methods */
|
/* only userdata, tables and nil can have getglobal tag methods */
|
||||||
case LUA_T_USERDATA: case LUA_T_ARRAY: case LUA_T_NIL: {
|
case LUA_T_USERDATA: case LUA_T_ARRAY: case LUA_T_NIL: {
|
||||||
@ -177,7 +177,7 @@ void luaV_getglobal (TaggedString *ts) {
|
|||||||
if (ttype(im) != LUA_T_NIL) { /* is there a tag method? */
|
if (ttype(im) != LUA_T_NIL) { /* is there a tag method? */
|
||||||
struct Stack *S = &L->stack;
|
struct Stack *S = &L->stack;
|
||||||
ttype(S->top) = LUA_T_STRING;
|
ttype(S->top) = LUA_T_STRING;
|
||||||
tsvalue(S->top) = ts;
|
tsvalue(S->top) = gv->name; /* global name */
|
||||||
S->top++;
|
S->top++;
|
||||||
*S->top++ = *value;
|
*S->top++ = *value;
|
||||||
luaD_callTM(im, 2, 1);
|
luaD_callTM(im, 2, 1);
|
||||||
@ -190,18 +190,18 @@ void luaV_getglobal (TaggedString *ts) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void luaV_setglobal (TaggedString *ts) {
|
void luaV_setglobal (GlobalVar *gv) {
|
||||||
const TObject *oldvalue = &ts->u.s.globalval;
|
const TObject *oldvalue = &gv->value;
|
||||||
const TObject *im = luaT_getimbyObj(oldvalue, IM_SETGLOBAL);
|
const TObject *im = luaT_getimbyObj(oldvalue, IM_SETGLOBAL);
|
||||||
if (ttype(im) == LUA_T_NIL) /* is there a tag method? */
|
if (ttype(im) == LUA_T_NIL) /* is there a tag method? */
|
||||||
luaS_rawsetglobal(ts, --L->stack.top);
|
gv->value = *(--L->stack.top);
|
||||||
else {
|
else {
|
||||||
/* WARNING: caller must assure stack space */
|
/* WARNING: caller must assure stack space */
|
||||||
struct Stack *S = &L->stack;
|
struct Stack *S = &L->stack;
|
||||||
TObject newvalue;
|
TObject newvalue;
|
||||||
newvalue = *(S->top-1);
|
newvalue = *(S->top-1);
|
||||||
ttype(S->top-1) = LUA_T_STRING;
|
ttype(S->top-1) = LUA_T_STRING;
|
||||||
tsvalue(S->top-1) = ts;
|
tsvalue(S->top-1) = gv->name;
|
||||||
*S->top++ = *oldvalue;
|
*S->top++ = *oldvalue;
|
||||||
*S->top++ = newvalue;
|
*S->top++ = newvalue;
|
||||||
luaD_callTM(im, 3, 0);
|
luaD_callTM(im, 3, 0);
|
||||||
@ -370,7 +370,7 @@ StkId luaV_execute (const Closure *cl, const TProtoFunc *tf, StkId base) {
|
|||||||
|
|
||||||
case GETGLOBALW: aux += highbyte(*pc++);
|
case GETGLOBALW: aux += highbyte(*pc++);
|
||||||
case GETGLOBAL: aux += *pc++;
|
case GETGLOBAL: aux += *pc++;
|
||||||
luaV_getglobal(tsvalue(&consts[aux]));
|
luaV_getglobal(tsvalue(&consts[aux])->u.s.gv);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GETTABLE:
|
case GETTABLE:
|
||||||
@ -407,7 +407,7 @@ StkId luaV_execute (const Closure *cl, const TProtoFunc *tf, StkId base) {
|
|||||||
|
|
||||||
case SETGLOBALW: aux += highbyte(*pc++);
|
case SETGLOBALW: aux += highbyte(*pc++);
|
||||||
case SETGLOBAL: aux += *pc++;
|
case SETGLOBAL: aux += *pc++;
|
||||||
luaV_setglobal(tsvalue(&consts[aux]));
|
luaV_setglobal(tsvalue(&consts[aux])->u.s.gv);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SETTABLEPOP:
|
case SETTABLEPOP:
|
||||||
|
6
lvm.h
6
lvm.h
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lvm.h,v 1.9 1999/08/16 20:52:00 roberto Exp roberto $
|
** $Id: lvm.h,v 1.10 1999/10/14 19:46:57 roberto Exp roberto $
|
||||||
** Lua virtual machine
|
** Lua virtual machine
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -24,8 +24,8 @@ void luaV_setn (Hash *t, int val);
|
|||||||
void luaV_gettable (void);
|
void luaV_gettable (void);
|
||||||
void luaV_settable (const TObject *t);
|
void luaV_settable (const TObject *t);
|
||||||
void luaV_rawsettable (const TObject *t);
|
void luaV_rawsettable (const TObject *t);
|
||||||
void luaV_getglobal (TaggedString *ts);
|
void luaV_getglobal (GlobalVar *gv);
|
||||||
void luaV_setglobal (TaggedString *ts);
|
void luaV_setglobal (GlobalVar *gv);
|
||||||
StkId luaV_execute (const Closure *cl, const TProtoFunc *tf, StkId base);
|
StkId luaV_execute (const Closure *cl, const TProtoFunc *tf, StkId base);
|
||||||
void luaV_closure (int nelems);
|
void luaV_closure (int nelems);
|
||||||
void luaV_comparison (lua_Type ttype_less, lua_Type ttype_equal,
|
void luaV_comparison (lua_Type ttype_less, lua_Type ttype_equal,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user