aboutsummaryrefslogtreecommitdiff
path: root/lref.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-10-04 15:50:24 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-10-04 15:50:24 -0200
commit1f7103e05d01a6a4c300a73bcfc8d9b17b2c20a4 (patch)
tree103b57aa472bced30c599536bfac78d3e94f7130 /lref.c
parentdcc10accea47fa1475c627de6f7c3e3f7eeec27b (diff)
downloadlua-1f7103e05d01a6a4c300a73bcfc8d9b17b2c20a4.tar.gz
lua-1f7103e05d01a6a4c300a73bcfc8d9b17b2c20a4.tar.bz2
lua-1f7103e05d01a6a4c300a73bcfc8d9b17b2c20a4.zip
implementation of lua_ref (previously in module `lmem').
Diffstat (limited to 'lref.c')
-rw-r--r--lref.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/lref.c b/lref.c
new file mode 100644
index 00000000..2479141c
--- /dev/null
+++ b/lref.c
@@ -0,0 +1,78 @@
1/*
2** $Id: $
3** REF mechanism
4** See Copyright Notice in lua.h
5*/
6
7
8#include "lmem.h"
9#include "lref.h"
10#include "lstate.h"
11#include "lua.h"
12
13
14int luaR_ref (const TObject *o, int lock) {
15 int ref;
16 if (ttype(o) == LUA_T_NIL)
17 ref = LUA_REFNIL;
18 else {
19 for (ref=0; ref<L->refSize; ref++)
20 if (L->refArray[ref].status == FREE)
21 break;
22 if (ref == L->refSize) { /* no more empty spaces? */
23 luaM_growvector(L->refArray, L->refSize, 1, struct ref, refEM, MAX_INT);
24 L->refSize++;
25 }
26 L->refArray[ref].o = *o;
27 L->refArray[ref].status = lock ? LOCK : HOLD;
28 }
29 return ref;
30}
31
32
33void lua_unref (int ref) {
34 if (ref >= 0 && ref < L->refSize)
35 L->refArray[ref].status = FREE;
36}
37
38
39const TObject *luaR_getref (int ref) {
40 if (ref == LUA_REFNIL)
41 return &luaO_nilobject;
42 if (ref >= 0 && ref < L->refSize &&
43 (L->refArray[ref].status == LOCK || L->refArray[ref].status == HOLD))
44 return &L->refArray[ref].o;
45 else
46 return NULL;
47}
48
49
50static int ismarked (const TObject *o) {
51 /* valid only for locked objects */
52 switch (o->ttype) {
53 case LUA_T_STRING: case LUA_T_USERDATA:
54 return o->value.ts->marked;
55 case LUA_T_ARRAY:
56 return o->value.a->marked;
57 case LUA_T_CLOSURE:
58 return o->value.cl->marked;
59 case LUA_T_PROTO:
60 return o->value.tf->marked;
61#ifdef DEBUG
62 case LUA_T_LINE: case LUA_T_CLMARK:
63 case LUA_T_CMARK: case LUA_T_PMARK:
64 LUA_INTERNALERROR("invalid type");
65#endif
66 default: /* nil, number or cproto */
67 return 1;
68 }
69}
70
71
72void luaR_invalidaterefs (void) {
73 int i;
74 for (i=0; i<L->refSize; i++)
75 if (L->refArray[i].status == HOLD && !ismarked(&L->refArray[i].o))
76 L->refArray[i].status = COLLECTED;
77}
78