aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c24
-rw-r--r--lgc.c46
-rw-r--r--lobject.h3
-rw-r--r--ltable.c1
-rw-r--r--ltm.c2
-rw-r--r--ltm.h1
6 files changed, 33 insertions, 44 deletions
diff --git a/lapi.c b/lapi.c
index 30e4d268..1331d4c4 100644
--- a/lapi.c
+++ b/lapi.c
@@ -695,28 +695,7 @@ LUA_API void lua_newuserdatabox (lua_State *L, void *p) {
695} 695}
696 696
697 697
698LUA_API int lua_getweakmode (lua_State *L, int index) { 698LUA_API int lua_pushupvalues (lua_State *L) {
699 StkId t;
700 int mode;
701 lua_lock(L);
702 t = luaA_index(L, index);
703 api_check(L, ttype(t) == LUA_TTABLE);
704 mode = hvalue(t)->weakmode;
705 lua_unlock(L);
706 return mode;
707}
708
709
710LUA_API void lua_setweakmode (lua_State *L, int mode) {
711 lua_lock(L);
712 api_check(L, ttype(L->top-1) == LUA_TTABLE);
713 hvalue(L->top-1)->weakmode = cast(lu_byte, mode);
714 lua_unlock(L);
715}
716
717
718
719LUA_API void lua_pushupvalues (lua_State *L) {
720 TObject *func; 699 TObject *func;
721 int n, i; 700 int n, i;
722 lua_lock(L); 701 lua_lock(L);
@@ -730,6 +709,7 @@ LUA_API void lua_pushupvalues (lua_State *L) {
730 L->top++; 709 L->top++;
731 } 710 }
732 lua_unlock(L); 711 lua_unlock(L);
712 return n;
733} 713}
734 714
735 715
diff --git a/lgc.c b/lgc.c
index d7971346..64eee046 100644
--- a/lgc.c
+++ b/lgc.c
@@ -4,6 +4,8 @@
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
6 6
7#include <string.h>
8
7#include "lua.h" 9#include "lua.h"
8 10
9#include "ldebug.h" 11#include "ldebug.h"
@@ -22,6 +24,7 @@
22typedef struct GCState { 24typedef struct GCState {
23 Table *tmark; /* list of marked tables to be visited */ 25 Table *tmark; /* list of marked tables to be visited */
24 Table *toclear; /* list of visited weak tables (to be cleared after GC) */ 26 Table *toclear; /* list of visited weak tables (to be cleared after GC) */
27 lua_State *L;
25} GCState; 28} GCState;
26 29
27 30
@@ -119,8 +122,8 @@ static void markobject (GCState *st, TObject *o) {
119} 122}
120 123
121 124
122static void markstacks (lua_State *L, GCState *st) { 125static void markstacks (GCState *st) {
123 lua_State *L1 = L; 126 lua_State *L1 = st->L;
124 do { /* for each thread */ 127 do { /* for each thread */
125 StkId o, lim; 128 StkId o, lim;
126 for (o=L1->stack; o<L1->top; o++) 129 for (o=L1->stack; o<L1->top; o++)
@@ -130,15 +133,15 @@ static void markstacks (lua_State *L, GCState *st) {
130 for (; o<=lim; o++) setnilvalue(o); 133 for (; o<=lim; o++) setnilvalue(o);
131 lua_assert(L1->previous->next == L1 && L1->next->previous == L1); 134 lua_assert(L1->previous->next == L1 && L1->next->previous == L1);
132 L1 = L1->next; 135 L1 = L1->next;
133 } while (L1 != L); 136 } while (L1 != st->L);
134} 137}
135 138
136 139
137static void markudet (lua_State *L, GCState *st) { 140static void markudet (GCState *st) {
138 Udata *u; 141 Udata *u;
139 for (u = G(L)->rootudata; u; u = u->uv.next) 142 for (u = G(st->L)->rootudata; u; u = u->uv.next)
140 marktable(st, u->uv.eventtable); 143 marktable(st, u->uv.eventtable);
141 for (u = G(L)->tmudata; u; u = u->uv.next) 144 for (u = G(st->L)->tmudata; u; u = u->uv.next)
142 marktable(st, u->uv.eventtable); 145 marktable(st, u->uv.eventtable);
143} 146}
144 147
@@ -152,13 +155,20 @@ static void removekey (Node *n) {
152 155
153static void traversetable (GCState *st, Table *h) { 156static void traversetable (GCState *st, Table *h) {
154 int i; 157 int i;
155 int mode = h->weakmode; 158 const TObject *mode;
159 int weakkey = 0;
160 int weakvalue = 0;
161 marktable(st, h->eventtable);
162 mode = fasttm(st->L, h->eventtable, TM_WEAKMODE);
156 if (mode) { /* weak table? must be cleared after GC... */ 163 if (mode) { /* weak table? must be cleared after GC... */
157 h->mark = st->toclear; /* put in the appropriate list */ 164 h->mark = st->toclear; /* put in the appropriate list */
158 st->toclear = h; 165 st->toclear = h;
166 if (ttype(mode) == LUA_TSTRING) {
167 weakkey = (strchr(svalue(mode), 'k') != NULL);
168 weakvalue = (strchr(svalue(mode), 'v') != NULL);
169 }
159 } 170 }
160 marktable(st, h->eventtable); 171 if (!weakvalue) {
161 if (!(mode & LUA_WEAK_VALUE)) {
162 i = sizearray(h); 172 i = sizearray(h);
163 while (i--) 173 while (i--)
164 markobject(st, &h->array[i]); 174 markobject(st, &h->array[i]);
@@ -168,18 +178,18 @@ static void traversetable (GCState *st, Table *h) {
168 Node *n = node(h, i); 178 Node *n = node(h, i);
169 if (ttype(val(n)) != LUA_TNIL) { 179 if (ttype(val(n)) != LUA_TNIL) {
170 lua_assert(ttype(key(n)) != LUA_TNIL); 180 lua_assert(ttype(key(n)) != LUA_TNIL);
171 if (!(mode & LUA_WEAK_KEY)) 181 if (!weakkey) markobject(st, key(n));
172 markobject(st, key(n)); 182 if (!weakvalue) markobject(st, val(n));
173 if (!(mode & LUA_WEAK_VALUE))
174 markobject(st, val(n));
175 } 183 }
176 } 184 }
177} 185}
178 186
179 187
180static void markall (lua_State *L, GCState *st) { 188static void markall (GCState *st) {
181 markstacks(L, st); /* mark all stacks */ 189 lua_assert(hvalue(defaultet(st->L))->flags == cast(unsigned short, ~0));
182 markudet(L, st); /* mark userdata's event tables */ 190 /* table is unchanged */
191 markstacks(st); /* mark all stacks */
192 markudet(st); /* mark userdata's event tables */
183 while (st->tmark) { /* traverse marked tables */ 193 while (st->tmark) { /* traverse marked tables */
184 Table *h = st->tmark; /* get first table from list */ 194 Table *h = st->tmark; /* get first table from list */
185 st->tmark = h->mark; /* remove it from list */ 195 st->tmark = h->mark; /* remove it from list */
@@ -210,7 +220,6 @@ static int hasmark (const TObject *o) {
210static void cleartables (Table *h) { 220static void cleartables (Table *h) {
211 for (; h; h = h->mark) { 221 for (; h; h = h->mark) {
212 int i; 222 int i;
213 lua_assert(h->weakmode);
214 i = sizearray(h); 223 i = sizearray(h);
215 while (i--) { 224 while (i--) {
216 TObject *o = &h->array[i]; 225 TObject *o = &h->array[i];
@@ -421,9 +430,10 @@ void luaC_collect (lua_State *L, int all) {
421 430
422void luaC_collectgarbage (lua_State *L) { 431void luaC_collectgarbage (lua_State *L) {
423 GCState st; 432 GCState st;
433 st.L = L;
424 st.tmark = NULL; 434 st.tmark = NULL;
425 st.toclear = NULL; 435 st.toclear = NULL;
426 markall(L, &st); 436 markall(&st);
427 cleartables(st.toclear); 437 cleartables(st.toclear);
428 luaC_collect(L, 0); 438 luaC_collect(L, 0);
429 checkMbuffer(L); 439 checkMbuffer(L);
diff --git a/lobject.h b/lobject.h
index a8dcf35e..37bb16e8 100644
--- a/lobject.h
+++ b/lobject.h
@@ -214,9 +214,9 @@ typedef union Closure {
214*/ 214*/
215 215
216typedef struct Node { 216typedef struct Node {
217 struct Node *next; /* for chaining */
218 TObject _key; 217 TObject _key;
219 TObject _val; 218 TObject _val;
219 struct Node *next; /* for chaining */
220} Node; 220} Node;
221 221
222 222
@@ -226,7 +226,6 @@ typedef struct Table {
226 Node *node; 226 Node *node;
227 int sizearray; /* size of `array' array */ 227 int sizearray; /* size of `array' array */
228 lu_byte lsizenode; /* log2 of size of `node' array */ 228 lu_byte lsizenode; /* log2 of size of `node' array */
229 lu_byte weakmode;
230 unsigned short flags; /* 1<<p means tagmethod(p) is not present */ 229 unsigned short flags; /* 1<<p means tagmethod(p) is not present */
231 Node *firstfree; /* this position is free; all positions after it are full */ 230 Node *firstfree; /* this position is free; all positions after it are full */
232 struct Table *next; 231 struct Table *next;
diff --git a/ltable.c b/ltable.c
index 12d46e02..5d8d8f6e 100644
--- a/ltable.c
+++ b/ltable.c
@@ -274,7 +274,6 @@ Table *luaH_new (lua_State *L, int narray, int lnhash) {
274 t->next = G(L)->roottable; 274 t->next = G(L)->roottable;
275 G(L)->roottable = t; 275 G(L)->roottable = t;
276 t->mark = t; 276 t->mark = t;
277 t->weakmode = 0;
278 t->flags = cast(unsigned short, ~0); 277 t->flags = cast(unsigned short, ~0);
279 /* temporary values (kept only if some malloc fails) */ 278 /* temporary values (kept only if some malloc fails) */
280 t->array = NULL; 279 t->array = NULL;
diff --git a/ltm.c b/ltm.c
index 62c3b38a..f69c6f9f 100644
--- a/ltm.c
+++ b/ltm.c
@@ -26,7 +26,7 @@ const char *const luaT_typenames[] = {
26void luaT_init (lua_State *L) { 26void luaT_init (lua_State *L) {
27 static const char *const luaT_eventname[] = { /* ORDER TM */ 27 static const char *const luaT_eventname[] = { /* ORDER TM */
28 "gettable", "settable", "index", 28 "gettable", "settable", "index",
29 "gc", 29 "gc", "weakmode",
30 "add", "sub", "mul", "div", 30 "add", "sub", "mul", "div",
31 "pow", "unm", "lt", "concat", 31 "pow", "unm", "lt", "concat",
32 "call" 32 "call"
diff --git a/ltm.h b/ltm.h
index 053b6f90..eedcc32d 100644
--- a/ltm.h
+++ b/ltm.h
@@ -19,6 +19,7 @@ typedef enum {
19 TM_SETTABLE, 19 TM_SETTABLE,
20 TM_INDEX, 20 TM_INDEX,
21 TM_GC, 21 TM_GC,
22 TM_WEAKMODE,
22 TM_ADD, 23 TM_ADD,
23 TM_SUB, 24 TM_SUB,
24 TM_MUL, 25 TM_MUL,