diff --git a/lref.c b/lref.c new file mode 100644 index 00000000..2479141c --- /dev/null +++ b/lref.c @@ -0,0 +1,78 @@ +/* +** $Id: $ +** REF mechanism +** See Copyright Notice in lua.h +*/ + + +#include "lmem.h" +#include "lref.h" +#include "lstate.h" +#include "lua.h" + + +int luaR_ref (const TObject *o, int lock) { + int ref; + if (ttype(o) == LUA_T_NIL) + ref = LUA_REFNIL; + else { + for (ref=0; refrefSize; ref++) + if (L->refArray[ref].status == FREE) + break; + if (ref == L->refSize) { /* no more empty spaces? */ + luaM_growvector(L->refArray, L->refSize, 1, struct ref, refEM, MAX_INT); + L->refSize++; + } + L->refArray[ref].o = *o; + L->refArray[ref].status = lock ? LOCK : HOLD; + } + return ref; +} + + +void lua_unref (int ref) { + if (ref >= 0 && ref < L->refSize) + L->refArray[ref].status = FREE; +} + + +const TObject *luaR_getref (int ref) { + if (ref == LUA_REFNIL) + return &luaO_nilobject; + if (ref >= 0 && ref < L->refSize && + (L->refArray[ref].status == LOCK || L->refArray[ref].status == HOLD)) + return &L->refArray[ref].o; + else + return NULL; +} + + +static int ismarked (const TObject *o) { + /* valid only for locked objects */ + switch (o->ttype) { + case LUA_T_STRING: case LUA_T_USERDATA: + return o->value.ts->marked; + case LUA_T_ARRAY: + return o->value.a->marked; + case LUA_T_CLOSURE: + return o->value.cl->marked; + case LUA_T_PROTO: + return o->value.tf->marked; +#ifdef DEBUG + case LUA_T_LINE: case LUA_T_CLMARK: + case LUA_T_CMARK: case LUA_T_PMARK: + LUA_INTERNALERROR("invalid type"); +#endif + default: /* nil, number or cproto */ + return 1; + } +} + + +void luaR_invalidaterefs (void) { + int i; + for (i=0; irefSize; i++) + if (L->refArray[i].status == HOLD && !ismarked(&L->refArray[i].o)) + L->refArray[i].status = COLLECTED; +} + diff --git a/lref.h b/lref.h new file mode 100644 index 00000000..60e14e85 --- /dev/null +++ b/lref.h @@ -0,0 +1,17 @@ +/* +** $Id: $ +** REF mechanism +** See Copyright Notice in lua.h +*/ + +#ifndef lref_h +#define lref_h + +#include "lobject.h" + +int luaR_ref (const TObject *o, int lock); +const TObject *luaR_getref (int ref); +void luaR_invalidaterefs (void); + + +#endif