mirror of
https://github.com/lua/lua.git
synced 2025-01-14 05:43:00 +08:00
Global variables
This commit is contained in:
parent
e18f681333
commit
b8a049abed
71
lglobal.c
Normal file
71
lglobal.c
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
** $Id: $
|
||||
** Global variables
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "lbuiltin.h"
|
||||
#include "lglobal.h"
|
||||
#include "lmem.h"
|
||||
#include "lobject.h"
|
||||
#include "lstring.h"
|
||||
|
||||
|
||||
Symbol *luaG_global = NULL;
|
||||
int luaG_nglobal = 0;
|
||||
static int maxglobal = 0;
|
||||
|
||||
|
||||
|
||||
Word luaG_findsymbol (TaggedString *t)
|
||||
{
|
||||
if (maxglobal == 0) { /* first time? */
|
||||
maxglobal = 50;
|
||||
luaG_global = luaM_newvector(maxglobal, Symbol);
|
||||
luaB_predefine();
|
||||
}
|
||||
if (t->u.s.varindex == NOT_USED) {
|
||||
if (!t->marked) t->marked = 2; /* avoid GC of global variable names */
|
||||
if (luaG_nglobal >= maxglobal)
|
||||
maxglobal = luaM_growvector(&luaG_global, maxglobal, Symbol,
|
||||
symbolEM, MAX_WORD);
|
||||
t->u.s.varindex = luaG_nglobal;
|
||||
luaG_global[luaG_nglobal].varname = t;
|
||||
s_ttype(luaG_nglobal) = LUA_T_NIL;
|
||||
luaG_nglobal++;
|
||||
}
|
||||
return t->u.s.varindex;
|
||||
}
|
||||
|
||||
|
||||
Word luaG_findsymbolbyname (char *name)
|
||||
{
|
||||
return luaG_findsymbol(luaS_new(name));
|
||||
}
|
||||
|
||||
|
||||
int luaG_globaldefined (char *name)
|
||||
{
|
||||
return s_ttype(luaG_findsymbolbyname(name)) != LUA_T_NIL;
|
||||
}
|
||||
|
||||
|
||||
int luaG_nextvar (Word next)
|
||||
{
|
||||
while (next < luaG_nglobal && s_ttype(next) == LUA_T_NIL)
|
||||
next++;
|
||||
return (next < luaG_nglobal ? next : -1);
|
||||
}
|
||||
|
||||
|
||||
char *luaG_travsymbol (int (*fn)(TObject *))
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<luaG_nglobal; i++)
|
||||
if (fn(&s_object(i)))
|
||||
return luaG_global[i].varname->str;
|
||||
return NULL;
|
||||
}
|
||||
|
35
lglobal.h
Normal file
35
lglobal.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
** $Id: $
|
||||
** Global variables
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#ifndef lglobal_h
|
||||
#define lglobal_h
|
||||
|
||||
|
||||
#include "lobject.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
TObject object;
|
||||
TaggedString *varname;
|
||||
} Symbol;
|
||||
|
||||
|
||||
extern Symbol *luaG_global; /* global variables */
|
||||
extern int luaG_nglobal; /* number of global variable (for luac) */
|
||||
|
||||
|
||||
Word luaG_findsymbolbyname (char *name);
|
||||
Word luaG_findsymbol (TaggedString *t);
|
||||
int luaG_globaldefined (char *name);
|
||||
int luaG_nextvar (Word next);
|
||||
char *luaG_travsymbol (int (*fn)(TObject *));
|
||||
|
||||
|
||||
#define s_object(i) (luaG_global[i].object)
|
||||
#define s_ttype(i) (ttype(&s_object(i)))
|
||||
|
||||
|
||||
#endif
|
251
table.c
251
table.c
@ -1,251 +0,0 @@
|
||||
/*
|
||||
** table.c
|
||||
** Module to control static tables
|
||||
*/
|
||||
|
||||
char *rcs_table="$Id: table.c,v 2.73 1997/07/07 16:44:26 roberto Exp roberto $";
|
||||
|
||||
#include "luamem.h"
|
||||
#include "auxlib.h"
|
||||
#include "func.h"
|
||||
#include "opcode.h"
|
||||
#include "tree.h"
|
||||
#include "hash.h"
|
||||
#include "table.h"
|
||||
#include "inout.h"
|
||||
#include "lua.h"
|
||||
#include "fallback.h"
|
||||
#include "luadebug.h"
|
||||
|
||||
|
||||
#define BUFFER_BLOCK 256
|
||||
|
||||
Symbol *lua_table = NULL;
|
||||
Word lua_ntable = 0;
|
||||
static Long lua_maxsymbol = 0;
|
||||
|
||||
|
||||
#define GARBAGE_BLOCK 100
|
||||
|
||||
|
||||
static TaggedString *luaI_createfixedstring (char *name)
|
||||
{
|
||||
TaggedString *ts = luaI_createstring(name);
|
||||
luaI_fixstring(ts);
|
||||
return ts;
|
||||
}
|
||||
|
||||
void luaI_initsymbol (void)
|
||||
{
|
||||
lua_maxsymbol = BUFFER_BLOCK;
|
||||
lua_table = newvector(lua_maxsymbol, Symbol);
|
||||
luaI_predefine();
|
||||
}
|
||||
|
||||
|
||||
void luaI_initconstant (void)
|
||||
{
|
||||
/* pre-register mem error messages, to avoid loop when error arises */
|
||||
luaI_createfixedstring(tableEM);
|
||||
luaI_createfixedstring(memEM);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Given a name, search it at symbol table and return its index. If not
|
||||
** found, allocate it.
|
||||
*/
|
||||
Word luaI_findsymbol (TaggedString *t)
|
||||
{
|
||||
if (t->u.s.varindex == NOT_USED)
|
||||
{
|
||||
if (lua_ntable == lua_maxsymbol)
|
||||
lua_maxsymbol = growvector(&lua_table, lua_maxsymbol, Symbol,
|
||||
symbolEM, MAX_WORD);
|
||||
t->u.s.varindex = lua_ntable;
|
||||
lua_table[lua_ntable].varname = t;
|
||||
s_ttype(lua_ntable) = LUA_T_NIL;
|
||||
lua_ntable++;
|
||||
}
|
||||
return t->u.s.varindex;
|
||||
}
|
||||
|
||||
|
||||
Word luaI_findsymbolbyname (char *name)
|
||||
{
|
||||
return luaI_findsymbol(luaI_createfixedstring(name));
|
||||
}
|
||||
|
||||
|
||||
void luaI_releasestring (TaggedString *t)
|
||||
{
|
||||
if (t->marked == 2) /* string has temporary mark? */
|
||||
t->marked = 0;
|
||||
}
|
||||
|
||||
|
||||
void luaI_fixstring (TaggedString *t)
|
||||
{
|
||||
if (t->marked < 3)
|
||||
t->marked = 3; /* avoid GC */
|
||||
}
|
||||
|
||||
|
||||
TaggedString *luaI_createtempstring (char *name)
|
||||
{
|
||||
TaggedString *ts = luaI_createstring(name);
|
||||
if (!ts->marked)
|
||||
ts->marked = 2; /* avoid (temporarily) GC */
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
int luaI_globaldefined (char *name)
|
||||
{
|
||||
return ttype(&lua_table[luaI_findsymbolbyname(name)].object) != LUA_T_NIL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Traverse symbol table objects
|
||||
*/
|
||||
static char *lua_travsymbol (int (*fn)(TObject *))
|
||||
{
|
||||
Word i;
|
||||
for (i=0; i<lua_ntable; i++)
|
||||
if (fn(&s_object(i)))
|
||||
return lua_table[i].varname->str;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int lua_markobject (TObject *o)
|
||||
{/* if already marked, does not change mark value */
|
||||
if (ttype(o) == LUA_T_USERDATA ||
|
||||
(ttype(o) == LUA_T_STRING && !tsvalue(o)->marked))
|
||||
tsvalue(o)->marked = 1;
|
||||
else if (ttype(o) == LUA_T_ARRAY)
|
||||
lua_hashmark (avalue(o));
|
||||
else if ((o->ttype == LUA_T_FUNCTION || o->ttype == LUA_T_MARK)
|
||||
&& !o->value.tf->marked)
|
||||
luaI_funcmark(o->value.tf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* returns 0 if the object is going to be (garbage) collected
|
||||
*/
|
||||
int luaI_ismarked (TObject *o)
|
||||
{
|
||||
switch (o->ttype)
|
||||
{
|
||||
case LUA_T_STRING: case LUA_T_USERDATA:
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void call_nilIM (void)
|
||||
{ /* signals end of garbage collection */
|
||||
TObject t;
|
||||
ttype(&t) = LUA_T_NIL;
|
||||
luaI_gcIM(&t); /* end of list */
|
||||
}
|
||||
|
||||
/*
|
||||
** Garbage collection.
|
||||
** Delete all unused strings and arrays.
|
||||
*/
|
||||
static long gc_block = GARBAGE_BLOCK;
|
||||
static long gc_nentity = 0; /* total of strings, arrays, etc */
|
||||
|
||||
static void markall (void)
|
||||
{
|
||||
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 */
|
||||
}
|
||||
|
||||
|
||||
long lua_collectgarbage (long limit)
|
||||
{
|
||||
long recovered = 0;
|
||||
Hash *freetable;
|
||||
TaggedString *freestr;
|
||||
TFunc *freefunc;
|
||||
markall();
|
||||
luaI_invalidaterefs();
|
||||
freetable = luaI_hashcollector(&recovered);
|
||||
freestr = luaI_strcollector(&recovered);
|
||||
freefunc = luaI_funccollector(&recovered);
|
||||
gc_nentity -= recovered;
|
||||
gc_block = (limit == 0) ? 2*(gc_block-recovered) : gc_nentity+limit;
|
||||
luaI_hashcallIM(freetable);
|
||||
luaI_strcallIM(freestr);
|
||||
call_nilIM();
|
||||
luaI_hashfree(freetable);
|
||||
luaI_strfree(freestr);
|
||||
luaI_funcfree(freefunc);
|
||||
/*printf("total %d coletados %d\n", (int)gc_nentity, (int)recovered);*/
|
||||
return recovered;
|
||||
}
|
||||
|
||||
|
||||
void lua_pack (void)
|
||||
{
|
||||
if (++gc_nentity >= gc_block)
|
||||
lua_collectgarbage(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Internal function: return next global variable
|
||||
*/
|
||||
void luaI_nextvar (void)
|
||||
{
|
||||
Word next = lua_isnil(lua_getparam(1)) ? 0 :
|
||||
luaI_findsymbolbyname(luaL_check_string(1))+1;
|
||||
if (next != 0)
|
||||
luaL_arg_check(s_ttype(next-1)!=LUA_T_NIL, 1, "undefined global name");
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static TObject *functofind;
|
||||
static int checkfunc (TObject *o)
|
||||
{
|
||||
if (o->ttype == LUA_T_FUNCTION)
|
||||
return
|
||||
((functofind->ttype == LUA_T_FUNCTION || functofind->ttype == LUA_T_MARK)
|
||||
&& (functofind->value.tf == o->value.tf));
|
||||
if (o->ttype == LUA_T_CFUNCTION)
|
||||
return
|
||||
((functofind->ttype == LUA_T_CFUNCTION ||
|
||||
functofind->ttype == LUA_T_CMARK) &&
|
||||
(functofind->value.f == o->value.f));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
return "tag-method";
|
||||
else if ((*name = lua_travsymbol(checkfunc)) != NULL)
|
||||
return "global";
|
||||
else return "";
|
||||
}
|
||||
|
37
table.h
37
table.h
@ -1,37 +0,0 @@
|
||||
/*
|
||||
** Module to control static tables
|
||||
** TeCGraf - PUC-Rio
|
||||
** $Id: table.h,v 2.25 1997/05/26 14:42:36 roberto Exp roberto $
|
||||
*/
|
||||
|
||||
#ifndef table_h
|
||||
#define table_h
|
||||
|
||||
#include "tree.h"
|
||||
#include "opcode.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
TObject object;
|
||||
TaggedString *varname;
|
||||
} Symbol;
|
||||
|
||||
|
||||
extern Symbol *lua_table;
|
||||
extern Word lua_ntable;
|
||||
|
||||
void luaI_initsymbol (void);
|
||||
void luaI_initconstant (void);
|
||||
Word luaI_findsymbolbyname (char *name);
|
||||
Word luaI_findsymbol (TaggedString *t);
|
||||
int luaI_globaldefined (char *name);
|
||||
void luaI_nextvar (void);
|
||||
TaggedString *luaI_createtempstring (char *name);
|
||||
void luaI_releasestring (TaggedString *t);
|
||||
void luaI_fixstring (TaggedString *t);
|
||||
int lua_markobject (TObject *o);
|
||||
int luaI_ismarked (TObject *o);
|
||||
void lua_pack (void);
|
||||
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user