#include #include "luadebug.h" #include "table.h" #include "luamem.h" #include "func.h" #include "opcode.h" #include "inout.h" static TFunc *function_root = NULL; static LocVar *currvars = NULL; static int numcurrvars = 0; static int maxcurrvars = 0; /* ** Initialize TFunc struct */ void luaI_initTFunc (TFunc *f) { f->next = NULL; f->marked = 0; f->size = 0; f->code = NULL; f->lineDefined = 0; f->fileName = lua_parsedfile; f->locvars = NULL; } /* ** Insert function in list for GC */ void luaI_insertfunction (TFunc *f) { lua_pack(); f->next = function_root; function_root = f; f->marked = 0; } /* ** Free function */ void luaI_freefunc (TFunc *f) { luaI_free (f->code); luaI_free (f->locvars); luaI_free (f); } void luaI_funcfree (TFunc *l) { while (l) { TFunc *next = l->next; luaI_freefunc(l); l = next; } } /* ** Garbage collection function. */ TFunc *luaI_funccollector (long *acum) { TFunc *curr = function_root; TFunc *prev = NULL; TFunc *frees = NULL; long counter = 0; while (curr) { TFunc *next = curr->next; if (!curr->marked) { if (prev == NULL) function_root = next; else prev->next = next; curr->next = frees; frees = curr; ++counter; } else { curr->marked = 0; prev = curr; } curr = next; } *acum += counter; return frees; } void lua_funcinfo (lua_Object func, char **filename, int *linedefined) { TObject *f = luaI_Address(func); if (f->ttype == LUA_T_MARK || f->ttype == LUA_T_FUNCTION) { *filename = f->value.tf->fileName; *linedefined = f->value.tf->lineDefined; } else if (f->ttype == LUA_T_CMARK || f->ttype == LUA_T_CFUNCTION) { *filename = "(C)"; *linedefined = -1; } } /* ** Stores information to know that variable has been declared in given line */ void luaI_registerlocalvar (TaggedString *varname, int line) { if (numcurrvars >= maxcurrvars) maxcurrvars = growvector(&currvars, maxcurrvars, LocVar, "", MAX_WORD); currvars[numcurrvars].varname = varname; currvars[numcurrvars].line = line; numcurrvars++; } /* ** Stores information to know that variable has been out of scope in given line */ void luaI_unregisterlocalvar (int line) { luaI_registerlocalvar(NULL, line); } /* ** Copies "currvars" into a new area and store it in function header. ** The values (varname = NULL, line = -1) signal the end of vector. */ void luaI_closelocalvars (TFunc *func) { func->locvars = newvector (numcurrvars+1, LocVar); memcpy (func->locvars, currvars, numcurrvars*sizeof(LocVar)); func->locvars[numcurrvars].varname = NULL; func->locvars[numcurrvars].line = -1; numcurrvars = 0; /* prepares for next function */ } /* ** Look for n-esim local variable at line "line" in function "func". ** Returns NULL if not found. */ char *luaI_getlocalname (TFunc *func, int local_number, int line) { int count = 0; char *varname = NULL; LocVar *lv = func->locvars; if (lv == NULL) return NULL; for (; lv->line != -1 && lv->line < line; lv++) { if (lv->varname) /* register */ { if (++count == local_number) varname = lv->varname->str; } else /* unregister */ if (--count < local_number) varname = NULL; } return varname; }