aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-11-10 13:37:50 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-11-10 13:37:50 -0200
commit53fb65d39451f9245d8ed555f941829520ee6f24 (patch)
tree1bf6d58df6213d647270377b1bd231ef4cbfdd8c
parenta7fa7bafc808103cbb8e27a3c80168617bac8a4f (diff)
downloadlua-53fb65d39451f9245d8ed555f941829520ee6f24.tar.gz
lua-53fb65d39451f9245d8ed555f941829520ee6f24.tar.bz2
lua-53fb65d39451f9245d8ed555f941829520ee6f24.zip
better implementation of `lua_ref' (much better...)
-rw-r--r--lref.c47
-rw-r--r--lref.h15
2 files changed, 46 insertions, 16 deletions
diff --git a/lref.c b/lref.c
index 2479141c..5c22b63b 100644
--- a/lref.c
+++ b/lref.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: $ 2** $Id: lref.c,v 1.1 1999/10/04 17:50:24 roberto Exp roberto $
3** REF mechanism 3** REF mechanism
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -16,31 +16,36 @@ int luaR_ref (const TObject *o, int lock) {
16 if (ttype(o) == LUA_T_NIL) 16 if (ttype(o) == LUA_T_NIL)
17 ref = LUA_REFNIL; 17 ref = LUA_REFNIL;
18 else { 18 else {
19 for (ref=0; ref<L->refSize; ref++) 19 if (L->refFree != NONEXT) { /* is there a free place? */
20 if (L->refArray[ref].status == FREE) 20 ref = L->refFree;
21 break; 21 L->refFree = L->refArray[ref].st;
22 if (ref == L->refSize) { /* no more empty spaces? */ 22 }
23 else { /* no more free places */
23 luaM_growvector(L->refArray, L->refSize, 1, struct ref, refEM, MAX_INT); 24 luaM_growvector(L->refArray, L->refSize, 1, struct ref, refEM, MAX_INT);
24 L->refSize++; 25 ref = L->refSize++;
25 } 26 }
26 L->refArray[ref].o = *o; 27 L->refArray[ref].o = *o;
27 L->refArray[ref].status = lock ? LOCK : HOLD; 28 L->refArray[ref].st = lock ? LOCK : HOLD;
28 } 29 }
29 return ref; 30 return ref;
30} 31}
31 32
32 33
33void lua_unref (int ref) { 34void lua_unref (int ref) {
34 if (ref >= 0 && ref < L->refSize) 35 if (ref >= 0) {
35 L->refArray[ref].status = FREE; 36 if (ref >= L->refSize || L->refArray[ref].st >= 0)
37 lua_error("API error - invalid parameter for function `lua_unref'");
38 L->refArray[ref].st = L->refFree;
39 L->refFree = ref;
40 }
36} 41}
37 42
38 43
39const TObject *luaR_getref (int ref) { 44const TObject *luaR_getref (int ref) {
40 if (ref == LUA_REFNIL) 45 if (ref == LUA_REFNIL)
41 return &luaO_nilobject; 46 return &luaO_nilobject;
42 if (ref >= 0 && ref < L->refSize && 47 else if (0 <= ref && ref < L->refSize &&
43 (L->refArray[ref].status == LOCK || L->refArray[ref].status == HOLD)) 48 (L->refArray[ref].st == LOCK || L->refArray[ref].st == HOLD))
44 return &L->refArray[ref].o; 49 return &L->refArray[ref].o;
45 else 50 else
46 return NULL; 51 return NULL;
@@ -63,16 +68,28 @@ static int ismarked (const TObject *o) {
63 case LUA_T_CMARK: case LUA_T_PMARK: 68 case LUA_T_CMARK: case LUA_T_PMARK:
64 LUA_INTERNALERROR("invalid type"); 69 LUA_INTERNALERROR("invalid type");
65#endif 70#endif
66 default: /* nil, number or cproto */ 71 default: /* number or cproto */
67 return 1; 72 return 1;
68 } 73 }
69} 74}
70 75
71 76
77/* for internal debugging only; check if a link of free refs is valid */
78#define VALIDLINK(st,n) (NONEXT <= (st) && (st) < (n))
79
72void luaR_invalidaterefs (void) { 80void luaR_invalidaterefs (void) {
81 int n = L->refSize;
73 int i; 82 int i;
74 for (i=0; i<L->refSize; i++) 83 for (i=0; i<n; i++) {
75 if (L->refArray[i].status == HOLD && !ismarked(&L->refArray[i].o)) 84 struct ref *r = &L->refArray[i];
76 L->refArray[i].status = COLLECTED; 85 if (r->st == HOLD && !ismarked(&r->o))
86 r->st = COLLECTED;
87 LUA_ASSERT((r->st == LOCK && ismarked(&r->o)) ||
88 r->st == COLLECTED ||
89 r->st == NONEXT ||
90 (r->st < n && VALIDLINK(L->refArray[r->st].st, n)),
91 "inconsistent ref table");
92 }
93 LUA_ASSERT(VALIDLINK(L->refFree, n), "inconsistent ref table");
77} 94}
78 95
diff --git a/lref.h b/lref.h
index 60e14e85..180daab0 100644
--- a/lref.h
+++ b/lref.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: $ 2** $Id: lref.h,v 1.1 1999/10/04 17:50:24 roberto Exp roberto $
3** REF mechanism 3** REF mechanism
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -9,6 +9,19 @@
9 9
10#include "lobject.h" 10#include "lobject.h"
11 11
12
13#define NONEXT -1 /* to end the free list */
14#define HOLD -2
15#define COLLECTED -3
16#define LOCK -4
17
18
19struct ref {
20 TObject o;
21 int st; /* can be LOCK, HOLD, COLLECTED, or next (for free list) */
22};
23
24
12int luaR_ref (const TObject *o, int lock); 25int luaR_ref (const TObject *o, int lock);
13const TObject *luaR_getref (int ref); 26const TObject *luaR_getref (int ref);
14void luaR_invalidaterefs (void); 27void luaR_invalidaterefs (void);