3 ** Module to control static tables
6 char *rcs_table
="$Id: table.c,v 2.72 1997/06/17 18:09:31 roberto Exp $";
21 #define BUFFER_BLOCK 256
23 Symbol
*lua_table
= NULL
;
25 static Long lua_maxsymbol
= 0;
27 TaggedString
**lua_constant
= NULL
;
28 Word lua_nconstant
= 0;
29 static Long lua_maxconstant
= 0;
32 #define GARBAGE_BLOCK 100
35 void luaI_initsymbol (void)
37 lua_maxsymbol
= BUFFER_BLOCK
;
38 lua_table
= newvector(lua_maxsymbol
, Symbol
);
44 ** Initialise constant table with pre-defined constants
46 void luaI_initconstant (void)
48 lua_maxconstant
= BUFFER_BLOCK
;
49 lua_constant
= newvector(lua_maxconstant
, TaggedString
*);
50 /* pre-register mem error messages, to avoid loop when error arises */
51 luaI_findconstantbyname(tableEM
);
52 luaI_findconstantbyname(memEM
);
57 ** Given a name, search it at symbol table and return its index. If not
58 ** found, allocate it.
60 Word
luaI_findsymbol (TaggedString
*t
)
62 if (t
->u
.s
.varindex
== NOT_USED
)
64 if (lua_ntable
== lua_maxsymbol
)
65 lua_maxsymbol
= growvector(&lua_table
, lua_maxsymbol
, Symbol
,
67 t
->u
.s
.varindex
= lua_ntable
;
68 lua_table
[lua_ntable
].varname
= t
;
69 s_ttype(lua_ntable
) = LUA_T_NIL
;
72 return t
->u
.s
.varindex
;
76 Word
luaI_findsymbolbyname (char *name
)
78 return luaI_findsymbol(luaI_createfixedstring(name
));
83 ** Given a tree node, check it is has a correspondent constant index. If not,
86 Word
luaI_findconstant (TaggedString
*t
)
88 if (t
->u
.s
.constindex
== NOT_USED
)
90 if (lua_nconstant
== lua_maxconstant
)
91 lua_maxconstant
= growvector(&lua_constant
, lua_maxconstant
, TaggedString
*,
92 constantEM
, MAX_WORD
);
93 t
->u
.s
.constindex
= lua_nconstant
;
94 lua_constant
[lua_nconstant
] = t
;
97 return t
->u
.s
.constindex
;
101 Word
luaI_findconstantbyname (char *name
)
103 return luaI_findconstant(luaI_createfixedstring(name
));
106 TaggedString
*luaI_createfixedstring (char *name
)
108 TaggedString
*ts
= lua_createstring(name
);
110 ts
->marked
= 2; /* avoid GC */
115 int luaI_globaldefined (char *name
)
117 return ttype(&lua_table
[luaI_findsymbolbyname(name
)].object
) != LUA_T_NIL
;
122 ** Traverse symbol table objects
124 static char *lua_travsymbol (int (*fn
)(TObject
*))
127 for (i
=0; i
<lua_ntable
; i
++)
128 if (fn(&s_object(i
)))
129 return lua_table
[i
].varname
->str
;
135 ** Mark an object if it is a string or a unmarked array.
137 int lua_markobject (TObject
*o
)
138 {/* if already marked, does not change mark value */
139 if (ttype(o
) == LUA_T_USERDATA
||
140 (ttype(o
) == LUA_T_STRING
&& !tsvalue(o
)->marked
))
141 tsvalue(o
)->marked
= 1;
142 else if (ttype(o
) == LUA_T_ARRAY
)
143 lua_hashmark (avalue(o
));
144 else if ((o
->ttype
== LUA_T_FUNCTION
|| o
->ttype
== LUA_T_MARK
)
145 && !o
->value
.tf
->marked
)
146 o
->value
.tf
->marked
= 1;
151 * returns 0 if the object is going to be (garbage) collected
153 int luaI_ismarked (TObject
*o
)
157 case LUA_T_STRING
: case LUA_T_USERDATA
:
158 return o
->value
.ts
->marked
;
160 return o
->value
.tf
->marked
;
162 return o
->value
.a
->mark
;
163 default: /* nil, number, cfunction, or user data */
169 static void call_nilIM (void)
170 { /* signals end of garbage collection */
172 ttype(&t
) = LUA_T_NIL
;
173 luaI_gcIM(&t
); /* end of list */
177 ** Garbage collection.
178 ** Delete all unused strings and arrays.
180 static long gc_block
= GARBAGE_BLOCK
;
181 static long gc_nentity
= 0; /* total of strings, arrays, etc */
183 static void markall (void)
185 lua_travstack(lua_markobject
); /* mark stack objects */
186 lua_travsymbol(lua_markobject
); /* mark symbol table objects */
187 luaI_travlock(lua_markobject
); /* mark locked objects */
188 luaI_travfallbacks(lua_markobject
); /* mark fallbacks */
192 long lua_collectgarbage (long limit
)
196 TaggedString
*freestr
;
199 luaI_invalidaterefs();
200 freetable
= luaI_hashcollector(&recovered
);
201 freestr
= luaI_strcollector(&recovered
);
202 freefunc
= luaI_funccollector(&recovered
);
203 gc_nentity
-= recovered
;
204 gc_block
= (limit
== 0) ? 2*(gc_block
-recovered
) : gc_nentity
+limit
;
205 luaI_hashcallIM(freetable
);
206 luaI_strcallIM(freestr
);
208 luaI_hashfree(freetable
);
209 luaI_strfree(freestr
);
210 luaI_funcfree(freefunc
);
217 if (++gc_nentity
>= gc_block
)
218 lua_collectgarbage(0);
223 ** Internal function: return next global variable
225 void luaI_nextvar (void)
228 if (lua_isnil(lua_getparam(1)))
231 next
= luaI_findsymbolbyname(luaL_check_string(1)) + 1;
232 while (next
< lua_ntable
&& s_ttype(next
) == LUA_T_NIL
)
234 if (next
< lua_ntable
) {
235 lua_pushstring(lua_table
[next
].varname
->str
);
236 luaI_pushobject(&s_object(next
));
241 static TObject
*functofind
;
242 static int checkfunc (TObject
*o
)
244 if (o
->ttype
== LUA_T_FUNCTION
)
246 ((functofind
->ttype
== LUA_T_FUNCTION
|| functofind
->ttype
== LUA_T_MARK
)
247 && (functofind
->value
.tf
== o
->value
.tf
));
248 if (o
->ttype
== LUA_T_CFUNCTION
)
250 ((functofind
->ttype
== LUA_T_CFUNCTION
||
251 functofind
->ttype
== LUA_T_CMARK
) &&
252 (functofind
->value
.f
== o
->value
.f
));
257 char *lua_getobjname (lua_Object o
, char **name
)
258 { /* try to find a name for given function */
259 functofind
= luaI_Address(o
);
260 if ((*name
= luaI_travfallbacks(checkfunc
)) != NULL
)
262 else if ((*name
= lua_travsymbol(checkfunc
)) != NULL
)