diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-11-13 09:32:26 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-11-13 09:32:26 -0200 |
commit | 2f91f95d94d3a27fee6b45c31ea9ab631924a8bf (patch) | |
tree | bbc605f6643b4958f45536dc5f5f84297eda70c2 | |
parent | 42dd080a2e3e8fb6887ca1e066f53bb8fd23c9e7 (diff) | |
download | lua-2f91f95d94d3a27fee6b45c31ea9ab631924a8bf.tar.gz lua-2f91f95d94d3a27fee6b45c31ea9ab631924a8bf.tar.bz2 lua-2f91f95d94d3a27fee6b45c31ea9ab631924a8bf.zip |
better control over GCObjects
-rw-r--r-- | ldo.c | 4 | ||||
-rw-r--r-- | lfunc.c | 23 | ||||
-rw-r--r-- | lstate.c | 5 | ||||
-rw-r--r-- | lstate.h | 18 | ||||
-rw-r--r-- | lstring.c | 21 | ||||
-rw-r--r-- | ltable.c | 4 | ||||
-rw-r--r-- | ltests.c | 4 |
7 files changed, 49 insertions, 30 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.c,v 1.198 2002/11/06 19:08:00 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 1.199 2002/11/07 15:37:10 roberto Exp roberto $ |
3 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -105,7 +105,7 @@ static void correctstack (lua_State *L, TObject *oldstack) { | |||
105 | GCObject *up; | 105 | GCObject *up; |
106 | L->top = (L->top - oldstack) + L->stack; | 106 | L->top = (L->top - oldstack) + L->stack; |
107 | for (up = L->openupval; up != NULL; up = up->gch.next) | 107 | for (up = L->openupval; up != NULL; up = up->gch.next) |
108 | (&up->uv)->v = ((&up->uv)->v - oldstack) + L->stack; | 108 | gcotouv(up)->v = (gcotouv(up)->v - oldstack) + L->stack; |
109 | for (ci = L->base_ci; ci <= L->ci; ci++) { | 109 | for (ci = L->base_ci; ci <= L->ci; ci++) { |
110 | ci->base = (ci->base - oldstack) + L->stack; | 110 | ci->base = (ci->base - oldstack) + L->stack; |
111 | ci->top = (ci->top - oldstack) + L->stack; | 111 | ci->top = (ci->top - oldstack) + L->stack; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lfunc.c,v 1.60 2002/10/16 20:40:58 roberto Exp roberto $ | 2 | ** $Id: lfunc.c,v 1.61 2002/10/21 20:41:46 roberto Exp roberto $ |
3 | ** Auxiliary functions to manipulate prototypes and closures | 3 | ** Auxiliary functions to manipulate prototypes and closures |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -26,7 +26,7 @@ | |||
26 | 26 | ||
27 | Closure *luaF_newCclosure (lua_State *L, int nelems) { | 27 | Closure *luaF_newCclosure (lua_State *L, int nelems) { |
28 | Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); | 28 | Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems))); |
29 | luaC_link(L, cast(GCObject *, c), LUA_TFUNCTION); | 29 | luaC_link(L, valtogco(c), LUA_TFUNCTION); |
30 | c->c.isC = 1; | 30 | c->c.isC = 1; |
31 | c->c.nupvalues = cast(lu_byte, nelems); | 31 | c->c.nupvalues = cast(lu_byte, nelems); |
32 | return c; | 32 | return c; |
@@ -35,7 +35,7 @@ Closure *luaF_newCclosure (lua_State *L, int nelems) { | |||
35 | 35 | ||
36 | Closure *luaF_newLclosure (lua_State *L, int nelems, TObject *gt) { | 36 | Closure *luaF_newLclosure (lua_State *L, int nelems, TObject *gt) { |
37 | Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); | 37 | Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems))); |
38 | luaC_link(L, cast(GCObject *, c), LUA_TFUNCTION); | 38 | luaC_link(L, valtogco(c), LUA_TFUNCTION); |
39 | c->l.isC = 0; | 39 | c->l.isC = 0; |
40 | c->l.g = *gt; | 40 | c->l.g = *gt; |
41 | c->l.nupvalues = cast(lu_byte, nelems); | 41 | c->l.nupvalues = cast(lu_byte, nelems); |
@@ -45,35 +45,36 @@ Closure *luaF_newLclosure (lua_State *L, int nelems, TObject *gt) { | |||
45 | 45 | ||
46 | UpVal *luaF_findupval (lua_State *L, StkId level) { | 46 | UpVal *luaF_findupval (lua_State *L, StkId level) { |
47 | GCObject **pp = &L->openupval; | 47 | GCObject **pp = &L->openupval; |
48 | GCObject *p; | 48 | UpVal *p; |
49 | UpVal *v; | 49 | UpVal *v; |
50 | while ((p = *pp) != NULL && (&p->uv)->v >= level) { | 50 | while ((p = ngcotouv(*pp)) != NULL && p->v >= level) { |
51 | if ((&p->uv)->v == level) return &p->uv; | 51 | if (p->v == level) return p; |
52 | pp = &p->gch.next; | 52 | pp = &p->next; |
53 | } | 53 | } |
54 | v = luaM_new(L, UpVal); /* not found: create a new one */ | 54 | v = luaM_new(L, UpVal); /* not found: create a new one */ |
55 | v->tt = LUA_TUPVAL; | ||
55 | v->marked = 1; /* open upvalues should not be collected */ | 56 | v->marked = 1; /* open upvalues should not be collected */ |
56 | v->v = level; /* current value lives in the stack */ | 57 | v->v = level; /* current value lives in the stack */ |
57 | v->next = *pp; /* chain it in the proper position */ | 58 | v->next = *pp; /* chain it in the proper position */ |
58 | *pp = cast(GCObject *, v); | 59 | *pp = valtogco(v); |
59 | return v; | 60 | return v; |
60 | } | 61 | } |
61 | 62 | ||
62 | 63 | ||
63 | void luaF_close (lua_State *L, StkId level) { | 64 | void luaF_close (lua_State *L, StkId level) { |
64 | UpVal *p; | 65 | UpVal *p; |
65 | while ((p = &(L->openupval)->uv) != NULL && p->v >= level) { | 66 | while ((p = ngcotouv(L->openupval)) != NULL && p->v >= level) { |
66 | setobj(&p->value, p->v); /* save current value */ | 67 | setobj(&p->value, p->v); /* save current value */ |
67 | p->v = &p->value; /* now current value lives here */ | 68 | p->v = &p->value; /* now current value lives here */ |
68 | L->openupval = p->next; /* remove from `open' list */ | 69 | L->openupval = p->next; /* remove from `open' list */ |
69 | luaC_link(L, cast(GCObject *, p), LUA_TUPVAL); | 70 | luaC_link(L, valtogco(p), LUA_TUPVAL); |
70 | } | 71 | } |
71 | } | 72 | } |
72 | 73 | ||
73 | 74 | ||
74 | Proto *luaF_newproto (lua_State *L) { | 75 | Proto *luaF_newproto (lua_State *L) { |
75 | Proto *f = luaM_new(L, Proto); | 76 | Proto *f = luaM_new(L, Proto); |
76 | luaC_link(L, cast(GCObject *, f), LUA_TPROTO); | 77 | luaC_link(L, valtogco(f), LUA_TPROTO); |
77 | f->k = NULL; | 78 | f->k = NULL; |
78 | f->sizek = 0; | 79 | f->sizek = 0; |
79 | f->p = NULL; | 80 | f->p = NULL; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.c,v 1.108 2002/10/25 20:05:28 roberto Exp roberto $ | 2 | ** $Id: lstate.c,v 1.109 2002/10/25 21:30:00 roberto Exp roberto $ |
3 | ** Global State | 3 | ** Global State |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -125,7 +125,7 @@ static void preinit_state (lua_State *L) { | |||
125 | 125 | ||
126 | lua_State *luaE_newthread (lua_State *L) { | 126 | lua_State *luaE_newthread (lua_State *L) { |
127 | lua_State *L1 = newthread(L); | 127 | lua_State *L1 = newthread(L); |
128 | luaC_link(L, cast(GCObject *, L1), LUA_TTHREAD); | 128 | luaC_link(L, valtogco(L1), LUA_TTHREAD); |
129 | preinit_state(L1); | 129 | preinit_state(L1); |
130 | L1->l_G = L->l_G; | 130 | L1->l_G = L->l_G; |
131 | stack_init(L1, L); /* init stack */ | 131 | stack_init(L1, L); /* init stack */ |
@@ -137,6 +137,7 @@ lua_State *luaE_newthread (lua_State *L) { | |||
137 | LUA_API lua_State *lua_open (void) { | 137 | LUA_API lua_State *lua_open (void) { |
138 | lua_State *L = newthread(NULL); | 138 | lua_State *L = newthread(NULL); |
139 | if (L) { /* allocation OK? */ | 139 | if (L) { /* allocation OK? */ |
140 | L->tt = LUA_TTHREAD; | ||
140 | preinit_state(L); | 141 | preinit_state(L); |
141 | L->l_G = NULL; | 142 | L->l_G = NULL; |
142 | if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { | 143 | if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) { |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.h,v 1.99 2002/10/25 20:05:28 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 1.100 2002/11/06 19:08:00 roberto Exp roberto $ |
3 | ** Global State | 3 | ** Global State |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -144,6 +144,7 @@ struct lua_State { | |||
144 | lua_Hook hook; | 144 | lua_Hook hook; |
145 | TObject _gt; /* table of globals */ | 145 | TObject _gt; /* table of globals */ |
146 | GCObject *openupval; /* list of open upvalues in this stack */ | 146 | GCObject *openupval; /* list of open upvalues in this stack */ |
147 | GCObject *gclist; | ||
147 | struct lua_longjmp *errorJmp; /* current error recover point */ | 148 | struct lua_longjmp *errorJmp; /* current error recover point */ |
148 | ptrdiff_t errfunc; /* current error handling function (stack index) */ | 149 | ptrdiff_t errfunc; /* current error handling function (stack index) */ |
149 | }; | 150 | }; |
@@ -167,6 +168,21 @@ union GCObject { | |||
167 | }; | 168 | }; |
168 | 169 | ||
169 | 170 | ||
171 | /* macros to convert a GCObject into a specific value */ | ||
172 | #define gcotots(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts)) | ||
173 | #define gcotou(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u)) | ||
174 | #define gcotocl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl)) | ||
175 | #define gcotoh(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h)) | ||
176 | #define gcotop(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p)) | ||
177 | #define gcotouv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv)) | ||
178 | #define ngcotouv(o) \ | ||
179 | check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv)) | ||
180 | #define gcototh(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th)) | ||
181 | |||
182 | /* macro to convert any value into a GCObject */ | ||
183 | #define valtogco(v) (cast(GCObject *, (v))) | ||
184 | |||
185 | |||
170 | lua_State *luaE_newthread (lua_State *L); | 186 | lua_State *luaE_newthread (lua_State *L); |
171 | void luaE_freethread (lua_State *L, lua_State *L1); | 187 | void luaE_freethread (lua_State *L, lua_State *L1); |
172 | 188 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstring.c,v 1.75 2002/08/16 14:45:55 roberto Exp roberto $ | 2 | ** $Id: lstring.c,v 1.76 2002/08/30 19:09:21 roberto Exp roberto $ |
3 | ** String table (keeps all strings handled by Lua) | 3 | ** String table (keeps all strings handled by Lua) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -32,7 +32,7 @@ void luaS_resize (lua_State *L, int newsize) { | |||
32 | GCObject *p = tb->hash[i]; | 32 | GCObject *p = tb->hash[i]; |
33 | while (p) { /* for each node in the list */ | 33 | while (p) { /* for each node in the list */ |
34 | GCObject *next = p->gch.next; /* save next */ | 34 | GCObject *next = p->gch.next; /* save next */ |
35 | lu_hash h = (&p->ts)->tsv.hash; | 35 | lu_hash h = gcotots(p)->tsv.hash; |
36 | int h1 = lmod(h, newsize); /* new position */ | 36 | int h1 = lmod(h, newsize); /* new position */ |
37 | lua_assert(cast(int, h%newsize) == lmod(h, newsize)); | 37 | lua_assert(cast(int, h%newsize) == lmod(h, newsize)); |
38 | p->gch.next = newhash[h1]; /* chain it */ | 38 | p->gch.next = newhash[h1]; /* chain it */ |
@@ -59,7 +59,7 @@ static TString *newlstr (lua_State *L, const char *str, size_t l, lu_hash h) { | |||
59 | tb = &G(L)->strt; | 59 | tb = &G(L)->strt; |
60 | h = lmod(h, tb->size); | 60 | h = lmod(h, tb->size); |
61 | ts->tsv.next = tb->hash[h]; /* chain new entry */ | 61 | ts->tsv.next = tb->hash[h]; /* chain new entry */ |
62 | tb->hash[h] = cast(GCObject *, ts); | 62 | tb->hash[h] = valtogco(ts); |
63 | tb->nuse++; | 63 | tb->nuse++; |
64 | if (tb->nuse > cast(ls_nstr, tb->size) && tb->size <= MAX_INT/2) | 64 | if (tb->nuse > cast(ls_nstr, tb->size) && tb->size <= MAX_INT/2) |
65 | luaS_resize(L, tb->size*2); /* too crowded */ | 65 | luaS_resize(L, tb->size*2); /* too crowded */ |
@@ -68,17 +68,18 @@ static TString *newlstr (lua_State *L, const char *str, size_t l, lu_hash h) { | |||
68 | 68 | ||
69 | 69 | ||
70 | TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { | 70 | TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { |
71 | GCObject *ts; | 71 | GCObject *o; |
72 | lu_hash h = (lu_hash)l; /* seed */ | 72 | lu_hash h = (lu_hash)l; /* seed */ |
73 | size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */ | 73 | size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */ |
74 | size_t l1; | 74 | size_t l1; |
75 | for (l1=l; l1>=step; l1-=step) /* compute hash */ | 75 | for (l1=l; l1>=step; l1-=step) /* compute hash */ |
76 | h = h ^ ((h<<5)+(h>>2)+(unsigned char)(str[l1-1])); | 76 | h = h ^ ((h<<5)+(h>>2)+(unsigned char)(str[l1-1])); |
77 | for (ts = G(L)->strt.hash[lmod(h, G(L)->strt.size)]; | 77 | for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)]; |
78 | ts != NULL; | 78 | o != NULL; |
79 | ts = ts->gch.next) { | 79 | o = o->gch.next) { |
80 | if ((&ts->ts)->tsv.len == l && (memcmp(str, getstr(&ts->ts), l) == 0)) | 80 | TString *ts = gcotots(o); |
81 | return &ts->ts; | 81 | if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) |
82 | return ts; | ||
82 | } | 83 | } |
83 | return newlstr(L, str, l, h); /* not found */ | 84 | return newlstr(L, str, l, h); /* not found */ |
84 | } | 85 | } |
@@ -93,7 +94,7 @@ Udata *luaS_newudata (lua_State *L, size_t s) { | |||
93 | u->uv.metatable = hvalue(defaultmeta(L)); | 94 | u->uv.metatable = hvalue(defaultmeta(L)); |
94 | /* chain it on udata list */ | 95 | /* chain it on udata list */ |
95 | u->uv.next = G(L)->rootudata; | 96 | u->uv.next = G(L)->rootudata; |
96 | G(L)->rootudata = cast(GCObject *, u); | 97 | G(L)->rootudata = valtogco(u); |
97 | return u; | 98 | return u; |
98 | } | 99 | } |
99 | 100 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltable.c,v 1.119 2002/09/02 19:54:49 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 1.120 2002/11/07 15:37:10 roberto Exp roberto $ |
3 | ** Lua tables (hash) | 3 | ** Lua tables (hash) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -301,7 +301,7 @@ static void rehash (lua_State *L, Table *t) { | |||
301 | 301 | ||
302 | Table *luaH_new (lua_State *L, int narray, int lnhash) { | 302 | Table *luaH_new (lua_State *L, int narray, int lnhash) { |
303 | Table *t = luaM_new(L, Table); | 303 | Table *t = luaM_new(L, Table); |
304 | luaC_link(L, cast(GCObject *, t), LUA_TTABLE); | 304 | luaC_link(L, valtogco(t), LUA_TTABLE); |
305 | t->metatable = hvalue(defaultmeta(L)); | 305 | t->metatable = hvalue(defaultmeta(L)); |
306 | t->flags = cast(lu_byte, ~0); | 306 | t->flags = cast(lu_byte, ~0); |
307 | t->mode = 0; | 307 | t->mode = 0; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltests.c,v 1.139 2002/10/25 21:29:20 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 1.140 2002/11/07 15:37:10 roberto Exp roberto $ |
3 | ** Internal Module for Debugging of the Lua Implementation | 3 | ** Internal Module for Debugging of the Lua Implementation |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -326,7 +326,7 @@ static int string_query (lua_State *L) { | |||
326 | GCObject *ts; | 326 | GCObject *ts; |
327 | int n = 0; | 327 | int n = 0; |
328 | for (ts = tb->hash[s]; ts; ts = ts->gch.next) { | 328 | for (ts = tb->hash[s]; ts; ts = ts->gch.next) { |
329 | setsvalue2s(L->top, &ts->ts); | 329 | setsvalue2s(L->top, gcotots(ts)); |
330 | incr_top(L); | 330 | incr_top(L); |
331 | n++; | 331 | n++; |
332 | } | 332 | } |