|
@@ -168,12 +168,19 @@ static int gc_traverse_tab(global_State *g, GCtab *t)
|
|
while ((c = *modestr++)) {
|
|
while ((c = *modestr++)) {
|
|
if (c == 'k') weak |= LJ_GC_WEAKKEY;
|
|
if (c == 'k') weak |= LJ_GC_WEAKKEY;
|
|
else if (c == 'v') weak |= LJ_GC_WEAKVAL;
|
|
else if (c == 'v') weak |= LJ_GC_WEAKVAL;
|
|
- else if (c == 'K') weak = (int)(~0u & ~LJ_GC_WEAKVAL);
|
|
|
|
}
|
|
}
|
|
- if (weak > 0) { /* Weak tables are cleared in the atomic phase. */
|
|
|
|
- t->marked = (uint8_t)((t->marked & ~LJ_GC_WEAK) | weak);
|
|
|
|
- setgcrefr(t->gclist, g->gc.weak);
|
|
|
|
- setgcref(g->gc.weak, obj2gco(t));
|
|
|
|
|
|
+ if (weak) { /* Weak tables are cleared in the atomic phase. */
|
|
|
|
+#if LJ_HASFFI
|
|
|
|
+ CTState *cts = ctype_ctsG(g);
|
|
|
|
+ if (cts && cts->finalizer == t) {
|
|
|
|
+ weak = (int)(~0u & ~LJ_GC_WEAKVAL);
|
|
|
|
+ } else
|
|
|
|
+#endif
|
|
|
|
+ {
|
|
|
|
+ t->marked = (uint8_t)((t->marked & ~LJ_GC_WEAK) | weak);
|
|
|
|
+ setgcrefr(t->gclist, g->gc.weak);
|
|
|
|
+ setgcref(g->gc.weak, obj2gco(t));
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (weak == LJ_GC_WEAK) /* Nothing to mark if both keys/values are weak. */
|
|
if (weak == LJ_GC_WEAK) /* Nothing to mark if both keys/values are weak. */
|