diff options
Diffstat (limited to 'src/table.c')
-rw-r--r-- | src/table.c | 191 |
1 files changed, 94 insertions, 97 deletions
diff --git a/src/table.c b/src/table.c index 1a2ac96b..1d694c4e 100644 --- a/src/table.c +++ b/src/table.c @@ -3,9 +3,7 @@ ** Module to control static tables */ -char *rcs_table="$Id: table.c,v 2.38 1995/11/03 15:30:50 roberto Exp $"; - -/*#include <string.h>*/ +char *rcs_table="$Id: table.c,v 2.54 1996/05/06 14:29:35 roberto Exp $"; #include "mem.h" #include "opcode.h" @@ -21,61 +19,66 @@ char *rcs_table="$Id: table.c,v 2.38 1995/11/03 15:30:50 roberto Exp $"; #define BUFFER_BLOCK 256 Symbol *lua_table = NULL; -static Word lua_ntable = 0; +Word lua_ntable = 0; static Long lua_maxsymbol = 0; TaggedString **lua_constant = NULL; -static Word lua_nconstant = 0; +Word lua_nconstant = 0; static Long lua_maxconstant = 0; -#define GARBAGE_BLOCK 1024 -#define MIN_GARBAGE_BLOCK (GARBAGE_BLOCK/2) +#define GARBAGE_BLOCK 50 static void lua_nextvar (void); -static void setglobal (void); -static void getglobal (void); /* -** Initialise symbol table with internal functions +** Internal functions */ -static void lua_initsymbol (void) +static struct { + char *name; + lua_CFunction func; +} int_funcs[] = { + {"assert", luaI_assert}, + {"dofile", lua_internaldofile}, + {"dostring", lua_internaldostring}, + {"error", luaI_error}, + {"getglobal", luaI_getglobal}, + {"next", lua_next}, + {"nextvar", lua_nextvar}, + {"print", luaI_print}, + {"setfallback", luaI_setfallback}, + {"setglobal", luaI_setglobal}, + {"tonumber", lua_obj2number}, + {"tostring", luaI_tostring}, + {"type", luaI_type} +}; + +#define INTFUNCSIZE (sizeof(int_funcs)/sizeof(int_funcs[0])) + + +void luaI_initsymbol (void) { - Word n; - lua_maxsymbol = BUFFER_BLOCK; - lua_table = newvector(lua_maxsymbol, Symbol); - n = luaI_findsymbolbyname("next"); - s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = lua_next; - n = luaI_findsymbolbyname("dofile"); - s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = lua_internaldofile; - n = luaI_findsymbolbyname("setglobal"); - s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = setglobal; - n = luaI_findsymbolbyname("getglobal"); - s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = getglobal; - n = luaI_findsymbolbyname("nextvar"); - s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = lua_nextvar; - n = luaI_findsymbolbyname("type"); - s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = luaI_type; - n = luaI_findsymbolbyname("tonumber"); - s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = lua_obj2number; - n = luaI_findsymbolbyname("print"); - s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = lua_print; - n = luaI_findsymbolbyname("dostring"); - s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = lua_internaldostring; - n = luaI_findsymbolbyname("setfallback"); - s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = luaI_setfallback; - n = luaI_findsymbolbyname("error"); - s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = luaI_error; + int i; + lua_maxsymbol = BUFFER_BLOCK; + lua_table = newvector(lua_maxsymbol, Symbol); + for (i=0; i<INTFUNCSIZE; i++) + { + Word n = luaI_findsymbolbyname(int_funcs[i].name); + s_tag(n) = LUA_T_CFUNCTION; s_fvalue(n) = int_funcs[i].func; + } } /* ** Initialise constant table with pre-defined constants */ -void lua_initconstant (void) +void luaI_initconstant (void) { lua_maxconstant = BUFFER_BLOCK; lua_constant = newvector(lua_maxconstant, TaggedString *); + /* pre-register mem error messages, to avoid loop when error arises */ + luaI_findconstantbyname(tableEM); + luaI_findconstantbyname(memEM); } @@ -83,22 +86,15 @@ void lua_initconstant (void) ** Given a name, search it at symbol table and return its index. If not ** found, allocate it. */ -Word luaI_findsymbol (TreeNode *t) +Word luaI_findsymbol (TaggedString *t) { - if (lua_table == NULL) - lua_initsymbol(); if (t->varindex == NOT_USED) { if (lua_ntable == lua_maxsymbol) - { - if (lua_maxsymbol >= MAX_WORD) - lua_error("symbol table overflow"); - lua_maxsymbol *= 2; - if (lua_maxsymbol >= MAX_WORD) - lua_maxsymbol = MAX_WORD; - lua_table = growvector(lua_table, lua_maxsymbol, Symbol); - } + lua_maxsymbol = growvector(&lua_table, lua_maxsymbol, Symbol, + symbolEM, MAX_WORD); t->varindex = lua_ntable; + lua_table[lua_ntable].varname = t; s_tag(lua_ntable) = LUA_T_NIL; lua_ntable++; } @@ -108,7 +104,7 @@ Word luaI_findsymbol (TreeNode *t) Word luaI_findsymbolbyname (char *name) { - return luaI_findsymbol(lua_constcreate(name)); + return luaI_findsymbol(luaI_createfixedstring(name)); } @@ -116,23 +112,15 @@ Word luaI_findsymbolbyname (char *name) ** Given a tree node, check it is has a correspondent constant index. If not, ** allocate it. */ -Word luaI_findconstant (TreeNode *t) +Word luaI_findconstant (TaggedString *t) { - if (lua_constant == NULL) - lua_initconstant(); if (t->constindex == NOT_USED) { if (lua_nconstant == lua_maxconstant) - { - if (lua_maxconstant >= MAX_WORD) - lua_error("constant table overflow"); - lua_maxconstant *= 2; - if (lua_maxconstant >= MAX_WORD) - lua_maxconstant = MAX_WORD; - lua_constant = growvector(lua_constant, lua_maxconstant, TaggedString *); - } + lua_maxconstant = growvector(&lua_constant, lua_maxconstant, TaggedString *, + constantEM, MAX_WORD); t->constindex = lua_nconstant; - lua_constant[lua_nconstant] = &(t->ts); + lua_constant[lua_nconstant] = t; lua_nconstant++; } return t->constindex; @@ -141,7 +129,15 @@ Word luaI_findconstant (TreeNode *t) Word luaI_findconstantbyname (char *name) { - return luaI_findconstant(lua_constcreate(name)); + return luaI_findconstant(luaI_createfixedstring(name)); +} + +TaggedString *luaI_createfixedstring (char *name) +{ + TaggedString *ts = lua_createstring(name); + if (!ts->marked) + ts->marked = 2; /* avoid GC */ + return ts; } @@ -153,7 +149,7 @@ static char *lua_travsymbol (int (*fn)(Object *)) Word i; for (i=0; i<lua_ntable; i++) if (fn(&s_object(i))) - return luaI_nodebysymbol(i)->ts.str; + return lua_table[i].varname->str; return NULL; } @@ -162,7 +158,7 @@ static char *lua_travsymbol (int (*fn)(Object *)) ** Mark an object if it is a string or a unmarked array. */ int lua_markobject (Object *o) -{ +{/* if already marked, does not change mark value */ if (tag(o) == LUA_T_STRING && !tsvalue(o)->marked) tsvalue(o)->marked = 1; else if (tag(o) == LUA_T_ARRAY) @@ -173,27 +169,52 @@ int lua_markobject (Object *o) return 0; } +/* +* returns 0 if the object is going to be (garbage) collected +*/ +int luaI_ismarked (Object *o) +{ + switch (o->tag) + { + 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; + } +} + /* ** Garbage collection. ** Delete all unused strings and arrays. */ -void lua_pack (void) +Long luaI_collectgarbage (void) { - static Long block = GARBAGE_BLOCK; /* when garbage collector will be called */ - static Long nentity = 0; /* counter of new entities (strings and arrays) */ Long recovered = 0; - if (nentity++ < block) return; lua_travstack(lua_markobject); /* mark stack objects */ lua_travsymbol(lua_markobject); /* mark symbol table objects */ luaI_travlock(lua_markobject); /* mark locked objects */ luaI_travfallbacks(lua_markobject); /* mark fallbacks */ + luaI_invalidaterefs(); recovered += lua_strcollector(); recovered += lua_hashcollector(); recovered += luaI_funccollector(); - nentity = 0; /* reset counter */ - block=(16*block-7*recovered)/12; /* adapt block size */ - if (block < MIN_GARBAGE_BLOCK) block = MIN_GARBAGE_BLOCK; + return recovered; +} + +void lua_pack (void) +{ + static unsigned long block = GARBAGE_BLOCK; + static unsigned long nentity = 0; /* total of strings, arrays, etc */ + unsigned long recovered = 0; + if (nentity++ < block) return; + recovered = luaI_collectgarbage(); + block = block*2*(1.0 - (float)recovered/nentity); + nentity -= recovered; } @@ -225,36 +246,12 @@ static void lua_nextvar (void) } else { - TreeNode *t = luaI_nodebysymbol(next); - Object name; - tag(&name) = LUA_T_STRING; - tsvalue(&name) = &(t->ts); - luaI_pushobject(&name); + lua_pushstring(lua_table[next].varname->str); luaI_pushobject(&s_object(next)); } } -static void setglobal (void) -{ - lua_Object name = lua_getparam(1); - lua_Object value = lua_getparam(2); - if (!lua_isstring(name)) - lua_error("incorrect argument to function `setglobal'"); - lua_pushobject(value); - lua_storeglobal(lua_getstring(name)); -} - - -static void getglobal (void) -{ - lua_Object name = lua_getparam(1); - if (!lua_isstring(name)) - lua_error("incorrect argument to function `getglobal'"); - lua_pushobject(lua_getglobal(lua_getstring(name))); -} - - static Object *functofind; static int checkfunc (Object *o) { @@ -270,7 +267,7 @@ static int checkfunc (Object *o) } -char *getobjname (lua_Object o, char **name) +char *lua_getobjname (lua_Object o, char **name) { /* try to find a name for given function */ functofind = luaI_Address(o); if ((*name = luaI_travfallbacks(checkfunc)) != NULL) |