diff options
-rw-r--r-- | lfunc.c | 5 | ||||
-rw-r--r-- | lgc.c | 62 | ||||
-rw-r--r-- | llex.c | 9 | ||||
-rw-r--r-- | lobject.h | 12 | ||||
-rw-r--r-- | lstring.c | 5 | ||||
-rw-r--r-- | lstring.h | 12 | ||||
-rw-r--r-- | ltable.c | 4 |
7 files changed, 54 insertions, 55 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lfunc.c,v 1.56 2002/05/02 13:06:20 roberto Exp roberto $ | 2 | ** $Id: lfunc.c,v 1.57 2002/06/20 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 | */ |
@@ -54,6 +54,7 @@ UpVal *luaF_findupval (lua_State *L, StkId level) { | |||
54 | pp = &p->next; | 54 | pp = &p->next; |
55 | } | 55 | } |
56 | p = luaM_new(L, UpVal); /* not found: create a new one */ | 56 | p = luaM_new(L, UpVal); /* not found: create a new one */ |
57 | p->marked = 1; /* open upvalues should not be collected */ | ||
57 | p->v = level; /* current value lives in the stack */ | 58 | p->v = level; /* current value lives in the stack */ |
58 | p->next = *pp; /* chain it in the proper position */ | 59 | p->next = *pp; /* chain it in the proper position */ |
59 | *pp = p; | 60 | *pp = p; |
@@ -64,6 +65,8 @@ UpVal *luaF_findupval (lua_State *L, StkId level) { | |||
64 | void luaF_close (lua_State *L, StkId level) { | 65 | void luaF_close (lua_State *L, StkId level) { |
65 | UpVal *p; | 66 | UpVal *p; |
66 | while ((p = L->openupval) != NULL && p->v >= level) { | 67 | while ((p = L->openupval) != NULL && p->v >= level) { |
68 | lua_assert(p->marked); | ||
69 | p->marked = 0; | ||
67 | setobj(&p->value, p->v); /* save current value */ | 70 | setobj(&p->value, p->v); /* save current value */ |
68 | p->v = &p->value; /* now current value lives here */ | 71 | p->v = &p->value; /* now current value lives here */ |
69 | L->openupval = p->next; /* remove from `open' list */ | 72 | L->openupval = p->next; /* remove from `open' list */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 1.144 2002/08/05 14:50:39 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 1.145 2002/08/06 17:06:56 roberto Exp roberto $ |
3 | ** Garbage Collector | 3 | ** Garbage Collector |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -27,27 +27,26 @@ typedef struct GCState { | |||
27 | } GCState; | 27 | } GCState; |
28 | 28 | ||
29 | 29 | ||
30 | /* mark a string; marks larger than 1 cannot be changed */ | 30 | /* |
31 | #define strmark(s) {if ((s)->tsv.marked == 0) (s)->tsv.marked = 1;} | 31 | ** some userful bit tricks |
32 | */ | ||
33 | #define setbit(x,b) ((x) |= (1<<(b))) | ||
34 | #define resetbit(x,b) ((x) &= cast(lu_byte, ~(1<<(b)))) | ||
35 | #define testbit(x,b) ((x) & (1<<(b))) | ||
32 | 36 | ||
33 | 37 | ||
34 | /* unmarked tables are represented by pointing `mark' to themselves */ | 38 | #define strmark(s) setbit((s)->tsv.marked, 0) |
35 | #define ismarked(x) ((x)->mark != (x)) | 39 | #define strunmark(s) resetbit((s)->tsv.marked, 0) |
36 | 40 | ||
37 | 41 | ||
38 | 42 | ||
39 | /* mark tricks for userdata */ | 43 | /* mark tricks for userdata */ |
40 | #define isudmarked(u) (u->uv.len & 1) | 44 | #define isudmarked(u) testbit(u->uv.marked, 0) |
41 | #define markud(u) (u->uv.len |= 1) | 45 | #define markud(u) setbit(u->uv.marked, 0) |
42 | #define unmarkud(u) (u->uv.len &= (~(size_t)1)) | 46 | #define unmarkud(u) resetbit(u->uv.marked, 0) |
43 | |||
44 | #define isfinalized(u) (u->uv.len & 2) | ||
45 | #define markfinalized(u) (u->uv.len |= 2) | ||
46 | |||
47 | |||
48 | /* mark tricks for upvalues (assume that open upvalues are always marked) */ | ||
49 | #define isupvalmarked(uv) ((uv)->v != &(uv)->value) | ||
50 | 47 | ||
48 | #define isfinalized(u) testbit(u->uv.marked, 1) | ||
49 | #define markfinalized(u) setbit(u->uv.marked, 1) | ||
51 | 50 | ||
52 | 51 | ||
53 | #define ismarkable(o) (!((1 << ttype(o)) & \ | 52 | #define ismarkable(o) (!((1 << ttype(o)) & \ |
@@ -78,8 +77,9 @@ static void protomark (Proto *f) { | |||
78 | 77 | ||
79 | 78 | ||
80 | static void marktable (GCState *st, Table *h) { | 79 | static void marktable (GCState *st, Table *h) { |
81 | if (!ismarked(h)) { | 80 | if (!h->marked) { |
82 | h->mark = st->tmark; /* chain it for later traversal */ | 81 | h->marked = 1; |
82 | h->gclist = st->tmark; /* chain it for later traversal */ | ||
83 | st->tmark = h; | 83 | st->tmark = h; |
84 | } | 84 | } |
85 | } | 85 | } |
@@ -100,9 +100,9 @@ static void markclosure (GCState *st, Closure *cl) { | |||
100 | protomark(cl->l.p); | 100 | protomark(cl->l.p); |
101 | for (i=0; i<cl->l.nupvalues; i++) { /* mark its upvalues */ | 101 | for (i=0; i<cl->l.nupvalues; i++) { /* mark its upvalues */ |
102 | UpVal *u = cl->l.upvals[i]; | 102 | UpVal *u = cl->l.upvals[i]; |
103 | if (!isupvalmarked(u)) { | 103 | if (!u->marked) { |
104 | markobject(st, &u->value); | 104 | markobject(st, &u->value); |
105 | u->v = NULL; /* mark it! */ | 105 | u->marked = 1; |
106 | } | 106 | } |
107 | } | 107 | } |
108 | } | 108 | } |
@@ -222,7 +222,7 @@ static void traversetable (GCState *st, Table *h) { | |||
222 | if (h->mode & (WEAKKEY | WEAKVALUE)) { /* weak table? */ | 222 | if (h->mode & (WEAKKEY | WEAKVALUE)) { /* weak table? */ |
223 | weakkey = h->mode & WEAKKEY; | 223 | weakkey = h->mode & WEAKKEY; |
224 | weakvalue = h->mode & WEAKVALUE; | 224 | weakvalue = h->mode & WEAKVALUE; |
225 | h->mark = st->toclear; /* must be cleared after GC, ... */ | 225 | h->gclist = st->toclear; /* must be cleared after GC, ... */ |
226 | st->toclear = h; /* ... so put in the appropriate list */ | 226 | st->toclear = h; /* ... so put in the appropriate list */ |
227 | } | 227 | } |
228 | if (!weakvalue) { | 228 | if (!weakvalue) { |
@@ -245,7 +245,7 @@ static void traversetable (GCState *st, Table *h) { | |||
245 | static void propagatemarks (GCState *st) { | 245 | static void propagatemarks (GCState *st) { |
246 | while (st->tmark) { /* traverse marked tables */ | 246 | while (st->tmark) { /* traverse marked tables */ |
247 | Table *h = st->tmark; /* get first table from list */ | 247 | Table *h = st->tmark; /* get first table from list */ |
248 | st->tmark = h->mark; /* remove it from list */ | 248 | st->tmark = h->gclist; /* remove it from list */ |
249 | traversetable(st, h); | 249 | traversetable(st, h); |
250 | } | 250 | } |
251 | } | 251 | } |
@@ -256,7 +256,7 @@ static int hasmark (const TObject *o) { | |||
256 | case LUA_TUSERDATA: | 256 | case LUA_TUSERDATA: |
257 | return isudmarked(uvalue(o)); | 257 | return isudmarked(uvalue(o)); |
258 | case LUA_TTABLE: | 258 | case LUA_TTABLE: |
259 | return ismarked(hvalue(o)); | 259 | return hvalue(o)->marked; |
260 | case LUA_TFUNCTION: | 260 | case LUA_TFUNCTION: |
261 | return clvalue(o)->c.marked; | 261 | return clvalue(o)->c.marked; |
262 | case LUA_TSTRING: | 262 | case LUA_TSTRING: |
@@ -273,7 +273,7 @@ static int hasmark (const TObject *o) { | |||
273 | */ | 273 | */ |
274 | static void cleartablekeys (GCState *st) { | 274 | static void cleartablekeys (GCState *st) { |
275 | Table *h; | 275 | Table *h; |
276 | for (h = st->toclear; h; h = h->mark) { | 276 | for (h = st->toclear; h; h = h->gclist) { |
277 | lua_assert(h->mode & (WEAKKEY | WEAKVALUE)); | 277 | lua_assert(h->mode & (WEAKKEY | WEAKVALUE)); |
278 | if ((h->mode & WEAKKEY)) { /* table may have collected keys? */ | 278 | if ((h->mode & WEAKKEY)) { /* table may have collected keys? */ |
279 | int i = sizenode(h); | 279 | int i = sizenode(h); |
@@ -292,7 +292,7 @@ static void cleartablekeys (GCState *st) { | |||
292 | */ | 292 | */ |
293 | static void cleartablevalues (GCState *st) { | 293 | static void cleartablevalues (GCState *st) { |
294 | Table *h; | 294 | Table *h; |
295 | for (h = st->toclear; h; h = h->mark) { | 295 | for (h = st->toclear; h; h = h->gclist) { |
296 | if ((h->mode & WEAKVALUE)) { /* table may have collected values? */ | 296 | if ((h->mode & WEAKVALUE)) { /* table may have collected values? */ |
297 | int i = sizearray(h); | 297 | int i = sizearray(h); |
298 | while (i--) { | 298 | while (i--) { |
@@ -347,9 +347,8 @@ static void collectupval (lua_State *L) { | |||
347 | UpVal **v = &G(L)->rootupval; | 347 | UpVal **v = &G(L)->rootupval; |
348 | UpVal *curr; | 348 | UpVal *curr; |
349 | while ((curr = *v) != NULL) { | 349 | while ((curr = *v) != NULL) { |
350 | if (isupvalmarked(curr)) { | 350 | if (curr->marked) { |
351 | lua_assert(curr->v == NULL); | 351 | curr->marked = 0; /* unmark */ |
352 | curr->v = &curr->value; /* unmark */ | ||
353 | v = &curr->next; /* next */ | 352 | v = &curr->next; /* next */ |
354 | } | 353 | } |
355 | else { | 354 | else { |
@@ -364,8 +363,8 @@ static void collecttable (lua_State *L) { | |||
364 | Table **p = &G(L)->roottable; | 363 | Table **p = &G(L)->roottable; |
365 | Table *curr; | 364 | Table *curr; |
366 | while ((curr = *p) != NULL) { | 365 | while ((curr = *p) != NULL) { |
367 | if (ismarked(curr)) { | 366 | if (curr->marked) { |
368 | curr->mark = curr; /* unmark */ | 367 | curr->marked = 0; |
369 | p = &curr->next; | 368 | p = &curr->next; |
370 | } | 369 | } |
371 | else { | 370 | else { |
@@ -387,7 +386,7 @@ static void collectudata (lua_State *L) { | |||
387 | } | 386 | } |
388 | else { | 387 | else { |
389 | *p = curr->uv.next; | 388 | *p = curr->uv.next; |
390 | luaM_free(L, curr, sizeudata(curr->uv.len & (~(size_t)3))); | 389 | luaM_free(L, curr, sizeudata(curr->uv.len)); |
391 | } | 390 | } |
392 | } | 391 | } |
393 | } | 392 | } |
@@ -400,8 +399,7 @@ static void collectstrings (lua_State *L, int all) { | |||
400 | TString *curr; | 399 | TString *curr; |
401 | while ((curr = *p) != NULL) { | 400 | while ((curr = *p) != NULL) { |
402 | if (curr->tsv.marked && !all) { /* preserve? */ | 401 | if (curr->tsv.marked && !all) { /* preserve? */ |
403 | if (curr->tsv.marked < FIXMARK) /* does not change FIXMARKs */ | 402 | strunmark(curr); |
404 | curr->tsv.marked = 0; | ||
405 | p = &curr->tsv.nexthash; | 403 | p = &curr->tsv.nexthash; |
406 | } | 404 | } |
407 | else { /* collect */ | 405 | else { /* collect */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: llex.c,v 1.107 2002/07/08 18:14:36 roberto Exp roberto $ | 2 | ** $Id: llex.c,v 1.108 2002/07/10 20:43:53 roberto Exp roberto $ |
3 | ** Lexical Analyzer | 3 | ** Lexical Analyzer |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -39,8 +39,9 @@ void luaX_init (lua_State *L) { | |||
39 | int i; | 39 | int i; |
40 | for (i=0; i<NUM_RESERVED; i++) { | 40 | for (i=0; i<NUM_RESERVED; i++) { |
41 | TString *ts = luaS_new(L, token2string[i]); | 41 | TString *ts = luaS_new(L, token2string[i]); |
42 | luaS_fix(ts); /* reserved words are never collected */ | ||
42 | lua_assert(strlen(token2string[i])+1 <= TOKEN_LEN); | 43 | lua_assert(strlen(token2string[i])+1 <= TOKEN_LEN); |
43 | ts->tsv.marked = cast(unsigned short, RESERVEDMARK+i); /* reserved word */ | 44 | ts->tsv.reserved = cast(lu_byte, i+1); /* reserved word */ |
44 | } | 45 | } |
45 | } | 46 | } |
46 | 47 | ||
@@ -388,8 +389,8 @@ int luaX_lex (LexState *LS, SemInfo *seminfo) { | |||
388 | /* identifier or reserved word */ | 389 | /* identifier or reserved word */ |
389 | size_t l = readname(LS); | 390 | size_t l = readname(LS); |
390 | TString *ts = luaS_newlstr(LS->L, cast(char *, G(LS->L)->Mbuffer), l); | 391 | TString *ts = luaS_newlstr(LS->L, cast(char *, G(LS->L)->Mbuffer), l); |
391 | if (ts->tsv.marked >= RESERVEDMARK) /* reserved word? */ | 392 | if (ts->tsv.reserved > 0) /* reserved word? */ |
392 | return ts->tsv.marked-RESERVEDMARK+FIRST_RESERVED; | 393 | return ts->tsv.reserved - 1 + FIRST_RESERVED; |
393 | seminfo->ts = ts; | 394 | seminfo->ts = ts; |
394 | return TK_NAME; | 395 | return TK_NAME; |
395 | } | 396 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lobject.h,v 1.141 2002/08/05 14:08:02 roberto Exp roberto $ | 2 | ** $Id: lobject.h,v 1.142 2002/08/06 17:06:56 roberto Exp roberto $ |
3 | ** Type definitions for Lua objects | 3 | ** Type definitions for Lua objects |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -101,8 +101,9 @@ typedef union TString { | |||
101 | struct { | 101 | struct { |
102 | lu_hash hash; | 102 | lu_hash hash; |
103 | size_t len; | 103 | size_t len; |
104 | int marked; | ||
105 | union TString *nexthash; /* chain for hash table */ | 104 | union TString *nexthash; /* chain for hash table */ |
105 | lu_byte marked; | ||
106 | lu_byte reserved; | ||
106 | } tsv; | 107 | } tsv; |
107 | } TString; | 108 | } TString; |
108 | 109 | ||
@@ -117,7 +118,8 @@ typedef union Udata { | |||
117 | struct { | 118 | struct { |
118 | struct Table *metatable; | 119 | struct Table *metatable; |
119 | union Udata *next; /* chain for list of all udata */ | 120 | union Udata *next; /* chain for list of all udata */ |
120 | size_t len; /* least 2 bits reserved for gc mark */ | 121 | size_t len; |
122 | lu_byte marked; | ||
121 | } uv; | 123 | } uv; |
122 | } Udata; | 124 | } Udata; |
123 | 125 | ||
@@ -164,6 +166,7 @@ typedef struct UpVal { | |||
164 | TObject *v; /* points to stack or to its own value */ | 166 | TObject *v; /* points to stack or to its own value */ |
165 | struct UpVal *next; | 167 | struct UpVal *next; |
166 | TObject value; /* the value (when closed) */ | 168 | TObject value; /* the value (when closed) */ |
169 | lu_byte marked; | ||
167 | } UpVal; | 170 | } UpVal; |
168 | 171 | ||
169 | 172 | ||
@@ -219,11 +222,12 @@ typedef struct Table { | |||
219 | Node *node; | 222 | Node *node; |
220 | Node *firstfree; /* this position is free; all positions after it are full */ | 223 | Node *firstfree; /* this position is free; all positions after it are full */ |
221 | struct Table *next; | 224 | struct Table *next; |
222 | struct Table *mark; /* marked tables (point to itself when not marked) */ | 225 | struct Table *gclist; |
223 | int sizearray; /* size of `array' array */ | 226 | int sizearray; /* size of `array' array */ |
224 | lu_byte flags; /* 1<<p means tagmethod(p) is not present */ | 227 | lu_byte flags; /* 1<<p means tagmethod(p) is not present */ |
225 | lu_byte lsizenode; /* log2 of size of `node' array */ | 228 | lu_byte lsizenode; /* log2 of size of `node' array */ |
226 | lu_byte mode; | 229 | lu_byte mode; |
230 | lu_byte marked; | ||
227 | } Table; | 231 | } Table; |
228 | 232 | ||
229 | /* bit masks for `mode' */ | 233 | /* bit masks for `mode' */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstring.c,v 1.73 2002/03/20 18:37:13 roberto Exp roberto $ | 2 | ** $Id: lstring.c,v 1.74 2002/04/05 18:54:31 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 | */ |
@@ -53,6 +53,7 @@ static TString *newlstr (lua_State *L, const char *str, size_t l, lu_hash h) { | |||
53 | ts->tsv.len = l; | 53 | ts->tsv.len = l; |
54 | ts->tsv.hash = h; | 54 | ts->tsv.hash = h; |
55 | ts->tsv.marked = 0; | 55 | ts->tsv.marked = 0; |
56 | ts->tsv.reserved = 0; | ||
56 | memcpy(ts+1, str, l*sizeof(char)); | 57 | memcpy(ts+1, str, l*sizeof(char)); |
57 | ((char *)(ts+1))[l] = '\0'; /* ending 0 */ | 58 | ((char *)(ts+1))[l] = '\0'; /* ending 0 */ |
58 | tb = &G(L)->strt; | 59 | tb = &G(L)->strt; |
@@ -85,8 +86,8 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { | |||
85 | 86 | ||
86 | Udata *luaS_newudata (lua_State *L, size_t s) { | 87 | Udata *luaS_newudata (lua_State *L, size_t s) { |
87 | Udata *u; | 88 | Udata *u; |
88 | s = (s+3) & (~(size_t)3); /* make sure size is multiple of 4 */ | ||
89 | u = cast(Udata *, luaM_malloc(L, sizeudata(s))); | 89 | u = cast(Udata *, luaM_malloc(L, sizeudata(s))); |
90 | u->uv.marked = 0; | ||
90 | u->uv.len = s; | 91 | u->uv.len = s; |
91 | u->uv.metatable = hvalue(defaultmeta(L)); | 92 | u->uv.metatable = hvalue(defaultmeta(L)); |
92 | /* chain it on udata list */ | 93 | /* chain it on udata list */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstring.h,v 1.35 2001/11/28 20:13:13 roberto Exp roberto $ | 2 | ** $Id: lstring.h,v 1.36 2002/04/30 13:01:48 roberto Exp roberto $ |
3 | ** String table (keep all strings handled by Lua) | 3 | ** String table (keep all strings handled by Lua) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -13,14 +13,6 @@ | |||
13 | 13 | ||
14 | 14 | ||
15 | 15 | ||
16 | /* | ||
17 | ** any TString with mark>=FIXMARK is never collected. | ||
18 | ** Marks>=RESERVEDMARK are used to identify reserved words. | ||
19 | */ | ||
20 | #define FIXMARK 2 | ||
21 | #define RESERVEDMARK 3 | ||
22 | |||
23 | |||
24 | #define sizestring(l) (cast(lu_mem, sizeof(union TString))+ \ | 16 | #define sizestring(l) (cast(lu_mem, sizeof(union TString))+ \ |
25 | (cast(lu_mem, l)+1)*sizeof(char)) | 17 | (cast(lu_mem, l)+1)*sizeof(char)) |
26 | 18 | ||
@@ -30,7 +22,7 @@ | |||
30 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ | 22 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ |
31 | (sizeof(s)/sizeof(char))-1)) | 23 | (sizeof(s)/sizeof(char))-1)) |
32 | 24 | ||
33 | #define luaS_fix(s) ((s)->tsv.marked = FIXMARK) | 25 | #define luaS_fix(s) ((s)->tsv.marked |= (1<<4)) |
34 | 26 | ||
35 | void luaS_resize (lua_State *L, int newsize); | 27 | void luaS_resize (lua_State *L, int newsize); |
36 | Udata *luaS_newudata (lua_State *L, size_t s); | 28 | Udata *luaS_newudata (lua_State *L, size_t s); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltable.c,v 1.115 2002/08/05 14:45:32 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 1.116 2002/08/06 17:06:56 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 | */ |
@@ -307,8 +307,8 @@ Table *luaH_new (lua_State *L, int narray, int lnhash) { | |||
307 | t->metatable = hvalue(defaultmeta(L)); | 307 | t->metatable = hvalue(defaultmeta(L)); |
308 | t->next = G(L)->roottable; | 308 | t->next = G(L)->roottable; |
309 | G(L)->roottable = t; | 309 | G(L)->roottable = t; |
310 | t->mark = t; | ||
311 | t->flags = cast(lu_byte, ~0); | 310 | t->flags = cast(lu_byte, ~0); |
311 | t->marked = 0; | ||
312 | t->mode = 0; | 312 | t->mode = 0; |
313 | /* temporary values (kept only if some malloc fails) */ | 313 | /* temporary values (kept only if some malloc fails) */ |
314 | t->array = NULL; | 314 | t->array = NULL; |