1993-07-28 06:18:00 -07:00
|
|
|
/*
|
|
|
|
** table.c
|
|
|
|
** Module to control static tables
|
|
|
|
*/
|
|
|
|
|
1997-05-26 07:42:51 -07:00
|
|
|
char *rcs_table="$Id: table.c,v 2.69 1997/05/14 18:38:29 roberto Exp roberto $";
|
1993-07-28 06:18:00 -07:00
|
|
|
|
1997-03-31 06:19:01 -08:00
|
|
|
#include "luamem.h"
|
1997-04-04 07:35:37 -08:00
|
|
|
#include "auxlib.h"
|
1997-05-14 11:38:29 -07:00
|
|
|
#include "func.h"
|
1993-07-28 06:18:00 -07:00
|
|
|
#include "opcode.h"
|
1994-07-19 14:27:18 -07:00
|
|
|
#include "tree.h"
|
1993-07-28 06:18:00 -07:00
|
|
|
#include "hash.h"
|
|
|
|
#include "table.h"
|
1995-05-02 11:43:03 -07:00
|
|
|
#include "inout.h"
|
1993-07-28 06:18:00 -07:00
|
|
|
#include "lua.h"
|
1994-11-08 12:07:54 -08:00
|
|
|
#include "fallback.h"
|
1995-10-26 07:21:56 -07:00
|
|
|
#include "luadebug.h"
|
1993-07-28 06:18:00 -07:00
|
|
|
|
|
|
|
|
1994-07-19 14:27:18 -07:00
|
|
|
#define BUFFER_BLOCK 256
|
|
|
|
|
1995-09-15 13:47:53 -07:00
|
|
|
Symbol *lua_table = NULL;
|
1996-03-14 07:57:19 -08:00
|
|
|
Word lua_ntable = 0;
|
1994-08-03 07:15:46 -07:00
|
|
|
static Long lua_maxsymbol = 0;
|
1994-07-19 14:27:18 -07:00
|
|
|
|
1995-09-15 13:47:53 -07:00
|
|
|
TaggedString **lua_constant = NULL;
|
1996-03-14 07:57:19 -08:00
|
|
|
Word lua_nconstant = 0;
|
1994-08-03 07:15:46 -07:00
|
|
|
static Long lua_maxconstant = 0;
|
1994-07-19 14:27:18 -07:00
|
|
|
|
|
|
|
|
1997-05-26 07:42:51 -07:00
|
|
|
#define GARBAGE_BLOCK 100
|
1994-04-20 15:07:57 -07:00
|
|
|
|
1996-03-21 08:33:47 -08:00
|
|
|
|
1996-02-14 05:35:51 -08:00
|
|
|
void luaI_initsymbol (void)
|
1994-07-19 14:27:18 -07:00
|
|
|
{
|
1996-02-14 05:35:51 -08:00
|
|
|
lua_maxsymbol = BUFFER_BLOCK;
|
|
|
|
lua_table = newvector(lua_maxsymbol, Symbol);
|
1997-02-26 09:38:41 -08:00
|
|
|
luaI_predefine();
|
1994-07-19 14:27:18 -07:00
|
|
|
}
|
1994-04-20 15:07:57 -07:00
|
|
|
|
|
|
|
|
1994-07-19 14:27:18 -07:00
|
|
|
/*
|
|
|
|
** Initialise constant table with pre-defined constants
|
|
|
|
*/
|
1996-02-14 05:35:51 -08:00
|
|
|
void luaI_initconstant (void)
|
1994-07-19 14:27:18 -07:00
|
|
|
{
|
|
|
|
lua_maxconstant = BUFFER_BLOCK;
|
1994-11-23 06:32:00 -08:00
|
|
|
lua_constant = newvector(lua_maxconstant, TaggedString *);
|
1996-03-21 08:33:47 -08:00
|
|
|
/* pre-register mem error messages, to avoid loop when error arises */
|
1996-03-21 10:55:02 -08:00
|
|
|
luaI_findconstantbyname(tableEM);
|
|
|
|
luaI_findconstantbyname(memEM);
|
1994-07-19 14:27:18 -07:00
|
|
|
}
|
1994-04-20 15:07:57 -07:00
|
|
|
|
1994-11-03 14:33:40 -08:00
|
|
|
|
1993-07-28 06:18:00 -07:00
|
|
|
/*
|
|
|
|
** Given a name, search it at symbol table and return its index. If not
|
1994-07-19 14:27:18 -07:00
|
|
|
** found, allocate it.
|
1993-07-28 06:18:00 -07:00
|
|
|
*/
|
1996-02-12 10:32:40 -08:00
|
|
|
Word luaI_findsymbol (TaggedString *t)
|
1993-07-28 06:18:00 -07:00
|
|
|
{
|
1994-11-23 06:32:00 -08:00
|
|
|
if (t->varindex == NOT_USED)
|
1993-07-28 06:18:00 -07:00
|
|
|
{
|
1994-07-19 14:27:18 -07:00
|
|
|
if (lua_ntable == lua_maxsymbol)
|
1996-03-21 08:33:47 -08:00
|
|
|
lua_maxsymbol = growvector(&lua_table, lua_maxsymbol, Symbol,
|
|
|
|
symbolEM, MAX_WORD);
|
1994-11-14 13:40:14 -08:00
|
|
|
t->varindex = lua_ntable;
|
1996-01-26 10:03:19 -08:00
|
|
|
lua_table[lua_ntable].varname = t;
|
1997-03-11 10:44:28 -08:00
|
|
|
s_ttype(lua_ntable) = LUA_T_NIL;
|
1994-07-19 14:27:18 -07:00
|
|
|
lua_ntable++;
|
1993-07-28 06:18:00 -07:00
|
|
|
}
|
1994-11-14 13:40:14 -08:00
|
|
|
return t->varindex;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1994-12-20 13:20:36 -08:00
|
|
|
Word luaI_findsymbolbyname (char *name)
|
1994-11-14 13:40:14 -08:00
|
|
|
{
|
1996-02-26 13:00:27 -08:00
|
|
|
return luaI_findsymbol(luaI_createfixedstring(name));
|
1993-07-28 06:18:00 -07:00
|
|
|
}
|
|
|
|
|
1994-07-19 14:27:18 -07:00
|
|
|
|
1993-07-28 06:18:00 -07:00
|
|
|
/*
|
1995-10-13 08:16:25 -07:00
|
|
|
** Given a tree node, check it is has a correspondent constant index. If not,
|
|
|
|
** allocate it.
|
1993-07-28 06:18:00 -07:00
|
|
|
*/
|
1996-02-12 10:32:40 -08:00
|
|
|
Word luaI_findconstant (TaggedString *t)
|
1993-07-28 06:18:00 -07:00
|
|
|
{
|
1994-11-23 06:32:00 -08:00
|
|
|
if (t->constindex == NOT_USED)
|
1993-07-28 06:18:00 -07:00
|
|
|
{
|
1994-07-19 14:27:18 -07:00
|
|
|
if (lua_nconstant == lua_maxconstant)
|
1996-03-21 08:33:47 -08:00
|
|
|
lua_maxconstant = growvector(&lua_constant, lua_maxconstant, TaggedString *,
|
|
|
|
constantEM, MAX_WORD);
|
1994-11-14 13:40:14 -08:00
|
|
|
t->constindex = lua_nconstant;
|
1996-02-12 10:32:40 -08:00
|
|
|
lua_constant[lua_nconstant] = t;
|
1994-07-19 14:27:18 -07:00
|
|
|
lua_nconstant++;
|
1993-07-28 06:18:00 -07:00
|
|
|
}
|
1994-11-14 13:40:14 -08:00
|
|
|
return t->constindex;
|
1993-07-28 06:18:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1995-10-13 08:16:25 -07:00
|
|
|
Word luaI_findconstantbyname (char *name)
|
|
|
|
{
|
1996-02-26 13:00:27 -08:00
|
|
|
return luaI_findconstant(luaI_createfixedstring(name));
|
1996-02-12 10:32:40 -08:00
|
|
|
}
|
|
|
|
|
1996-02-26 13:00:27 -08:00
|
|
|
TaggedString *luaI_createfixedstring (char *name)
|
1996-02-12 10:32:40 -08:00
|
|
|
{
|
1996-02-26 13:00:27 -08:00
|
|
|
TaggedString *ts = lua_createstring(name);
|
|
|
|
if (!ts->marked)
|
|
|
|
ts->marked = 2; /* avoid GC */
|
|
|
|
return ts;
|
1995-10-13 08:16:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1997-04-07 07:48:53 -07:00
|
|
|
int luaI_globaldefined (char *name)
|
|
|
|
{
|
|
|
|
return ttype(&lua_table[luaI_findsymbolbyname(name)].object) != LUA_T_NIL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1994-04-20 15:07:57 -07:00
|
|
|
/*
|
|
|
|
** Traverse symbol table objects
|
|
|
|
*/
|
1997-03-31 06:02:58 -08:00
|
|
|
static char *lua_travsymbol (int (*fn)(TObject *))
|
1994-04-20 15:07:57 -07:00
|
|
|
{
|
1994-11-11 06:00:08 -08:00
|
|
|
Word i;
|
1994-04-20 15:07:57 -07:00
|
|
|
for (i=0; i<lua_ntable; i++)
|
1995-10-17 04:58:41 -07:00
|
|
|
if (fn(&s_object(i)))
|
1996-02-12 10:32:40 -08:00
|
|
|
return lua_table[i].varname->str;
|
1995-10-17 04:58:41 -07:00
|
|
|
return NULL;
|
1994-04-20 15:07:57 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1993-07-28 06:18:00 -07:00
|
|
|
/*
|
|
|
|
** Mark an object if it is a string or a unmarked array.
|
|
|
|
*/
|
1997-03-31 06:02:58 -08:00
|
|
|
int lua_markobject (TObject *o)
|
1996-02-12 10:32:40 -08:00
|
|
|
{/* if already marked, does not change mark value */
|
1997-03-26 14:22:41 -08:00
|
|
|
if (ttype(o) == LUA_T_USERDATA ||
|
|
|
|
(ttype(o) == LUA_T_STRING && !tsvalue(o)->marked))
|
1994-11-23 06:32:00 -08:00
|
|
|
tsvalue(o)->marked = 1;
|
1997-03-11 10:44:28 -08:00
|
|
|
else if (ttype(o) == LUA_T_ARRAY)
|
1994-11-23 06:32:00 -08:00
|
|
|
lua_hashmark (avalue(o));
|
1997-03-11 10:44:28 -08:00
|
|
|
else if ((o->ttype == LUA_T_FUNCTION || o->ttype == LUA_T_MARK)
|
1995-10-17 04:58:41 -07:00
|
|
|
&& !o->value.tf->marked)
|
1995-10-04 10:13:02 -07:00
|
|
|
o->value.tf->marked = 1;
|
1995-10-17 04:58:41 -07:00
|
|
|
return 0;
|
1993-07-28 06:18:00 -07:00
|
|
|
}
|
|
|
|
|
1996-04-22 11:00:37 -07:00
|
|
|
/*
|
|
|
|
* returns 0 if the object is going to be (garbage) collected
|
|
|
|
*/
|
1997-03-31 06:02:58 -08:00
|
|
|
int luaI_ismarked (TObject *o)
|
1996-04-22 11:00:37 -07:00
|
|
|
{
|
1997-03-11 10:44:28 -08:00
|
|
|
switch (o->ttype)
|
1996-04-22 11:00:37 -07:00
|
|
|
{
|
|
|
|
case LUA_T_STRING:
|
|
|
|
return o->value.ts->marked;
|
|
|
|
case LUA_T_FUNCTION:
|
|
|
|
return o->value.tf->marked;
|
|
|
|
case LUA_T_ARRAY:
|
|
|
|
return o->value.a->mark;
|
|
|
|
default: /* nil, number, cfunction, or user data */
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1994-04-20 15:07:57 -07:00
|
|
|
|
1997-03-21 13:39:57 -08:00
|
|
|
static void call_nilIM (void)
|
|
|
|
{ /* signals end of garbage collection */
|
1997-03-31 06:02:58 -08:00
|
|
|
TObject t;
|
1997-03-21 13:39:57 -08:00
|
|
|
ttype(&t) = LUA_T_NIL;
|
|
|
|
luaI_gcIM(&t); /* end of list */
|
|
|
|
}
|
|
|
|
|
1993-07-28 06:18:00 -07:00
|
|
|
/*
|
1994-04-20 15:07:57 -07:00
|
|
|
** Garbage collection.
|
|
|
|
** Delete all unused strings and arrays.
|
1993-07-28 06:18:00 -07:00
|
|
|
*/
|
1997-05-14 11:38:29 -07:00
|
|
|
static long gc_block = GARBAGE_BLOCK;
|
|
|
|
static long gc_nentity = 0; /* total of strings, arrays, etc */
|
|
|
|
|
|
|
|
static void markall (void)
|
1993-07-28 06:18:00 -07:00
|
|
|
{
|
1994-11-17 05:58:57 -08:00
|
|
|
lua_travstack(lua_markobject); /* mark stack objects */
|
|
|
|
lua_travsymbol(lua_markobject); /* mark symbol table objects */
|
|
|
|
luaI_travlock(lua_markobject); /* mark locked objects */
|
1995-10-04 10:13:02 -07:00
|
|
|
luaI_travfallbacks(lua_markobject); /* mark fallbacks */
|
1997-05-14 11:38:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1997-05-26 07:42:51 -07:00
|
|
|
long lua_collectgarbage (long limit)
|
1997-05-14 11:38:29 -07:00
|
|
|
{
|
|
|
|
long recovered = 0;
|
|
|
|
Hash *freetable;
|
|
|
|
TaggedString *freestr;
|
|
|
|
TFunc *freefunc;
|
|
|
|
markall();
|
|
|
|
freetable = luaI_hashcollector(&recovered);
|
|
|
|
freestr = luaI_strcollector(&recovered);
|
|
|
|
freefunc = luaI_funccollector(&recovered);
|
|
|
|
gc_nentity -= recovered;
|
1997-05-26 07:42:51 -07:00
|
|
|
gc_block = (limit == 0) ? 2*(gc_block-recovered) : gc_nentity+limit;
|
1997-05-14 11:38:29 -07:00
|
|
|
luaI_hashcallIM(freetable);
|
|
|
|
luaI_strcallIM(freestr);
|
1997-03-21 13:39:57 -08:00
|
|
|
call_nilIM();
|
1997-05-14 11:38:29 -07:00
|
|
|
luaI_hashfree(freetable);
|
|
|
|
luaI_strfree(freestr);
|
|
|
|
luaI_funcfree(freefunc);
|
1997-05-26 07:42:51 -07:00
|
|
|
return recovered;
|
1996-01-22 06:15:13 -08:00
|
|
|
}
|
|
|
|
|
1997-05-14 11:38:29 -07:00
|
|
|
|
1996-01-22 06:15:13 -08:00
|
|
|
void lua_pack (void)
|
|
|
|
{
|
1997-05-26 07:42:51 -07:00
|
|
|
if (++gc_nentity >= gc_block)
|
|
|
|
lua_collectgarbage(0);
|
1993-07-28 06:18:00 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
** Internal function: return next global variable
|
|
|
|
*/
|
1997-02-26 09:38:41 -08:00
|
|
|
void luaI_nextvar (void)
|
1993-07-28 06:18:00 -07:00
|
|
|
{
|
1997-04-04 07:35:37 -08:00
|
|
|
Word next;
|
|
|
|
if (lua_isnil(lua_getparam(1)))
|
|
|
|
next = 0;
|
|
|
|
else
|
1997-04-06 07:08:08 -07:00
|
|
|
next = luaI_findsymbolbyname(luaL_check_string(1)) + 1;
|
1997-04-04 07:35:37 -08:00
|
|
|
while (next < lua_ntable && s_ttype(next) == LUA_T_NIL)
|
|
|
|
next++;
|
|
|
|
if (next < lua_ntable) {
|
|
|
|
lua_pushstring(lua_table[next].varname->str);
|
|
|
|
luaI_pushobject(&s_object(next));
|
|
|
|
}
|
1993-07-28 06:18:00 -07:00
|
|
|
}
|
1994-11-21 13:41:09 -08:00
|
|
|
|
|
|
|
|
1997-03-31 06:02:58 -08:00
|
|
|
static TObject *functofind;
|
|
|
|
static int checkfunc (TObject *o)
|
1995-10-17 04:58:41 -07:00
|
|
|
{
|
1997-03-11 10:44:28 -08:00
|
|
|
if (o->ttype == LUA_T_FUNCTION)
|
1995-10-26 07:21:56 -07:00
|
|
|
return
|
1997-03-11 10:44:28 -08:00
|
|
|
((functofind->ttype == LUA_T_FUNCTION || functofind->ttype == LUA_T_MARK)
|
1995-10-26 07:21:56 -07:00
|
|
|
&& (functofind->value.tf == o->value.tf));
|
1997-03-11 10:44:28 -08:00
|
|
|
if (o->ttype == LUA_T_CFUNCTION)
|
1995-10-26 07:21:56 -07:00
|
|
|
return
|
1997-03-11 10:44:28 -08:00
|
|
|
((functofind->ttype == LUA_T_CFUNCTION ||
|
|
|
|
functofind->ttype == LUA_T_CMARK) &&
|
|
|
|
(functofind->value.f == o->value.f));
|
1995-10-26 07:21:56 -07:00
|
|
|
return 0;
|
1995-10-17 04:58:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1996-01-09 12:23:19 -08:00
|
|
|
char *lua_getobjname (lua_Object o, char **name)
|
1995-10-26 07:21:56 -07:00
|
|
|
{ /* try to find a name for given function */
|
|
|
|
functofind = luaI_Address(o);
|
1995-11-03 07:30:50 -08:00
|
|
|
if ((*name = luaI_travfallbacks(checkfunc)) != NULL)
|
1995-10-26 07:21:56 -07:00
|
|
|
return "fallback";
|
1995-11-03 07:30:50 -08:00
|
|
|
else if ((*name = lua_travsymbol(checkfunc)) != NULL)
|
|
|
|
return "global";
|
1995-10-26 07:21:56 -07:00
|
|
|
else return "";
|
1995-10-17 04:58:41 -07:00
|
|
|
}
|
|
|
|
|