lua

A copy of the Lua development repository
Log | Files | Refs | README

commit 1f7103e05d01a6a4c300a73bcfc8d9b17b2c20a4
parent dcc10accea47fa1475c627de6f7c3e3f7eeec27b
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date:   Mon,  4 Oct 1999 15:50:02 -0200

implementation of lua_ref (previously in module `lmem').

Diffstat:
Alref.c | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alref.h | 17+++++++++++++++++
2 files changed, 95 insertions(+), 0 deletions(-)

diff --git a/lref.c 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; ref<L->refSize; 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; i<L->refSize; 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 @@ -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