diff options
Diffstat (limited to 'src/lj_cdata.c')
-rw-r--r-- | src/lj_cdata.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/src/lj_cdata.c b/src/lj_cdata.c index ae66b4b5..11c84d8e 100644 --- a/src/lj_cdata.c +++ b/src/lj_cdata.c | |||
@@ -52,7 +52,18 @@ GCcdata *lj_cdata_newv(CTState *cts, CTypeID id, CTSize sz, CTSize align) | |||
52 | /* Free a C data object. */ | 52 | /* Free a C data object. */ |
53 | void LJ_FASTCALL lj_cdata_free(global_State *g, GCcdata *cd) | 53 | void LJ_FASTCALL lj_cdata_free(global_State *g, GCcdata *cd) |
54 | { | 54 | { |
55 | if (LJ_LIKELY(!cdataisv(cd))) { | 55 | if (LJ_UNLIKELY(cd->marked & LJ_GC_CDATA_FIN)) { |
56 | GCobj *root; | ||
57 | cd->marked = curwhite(g) | LJ_GC_FINALIZED; | ||
58 | if ((root = gcref(g->gc.mmudata)) != NULL) { | ||
59 | setgcrefr(cd->nextgc, root->gch.nextgc); | ||
60 | setgcref(root->gch.nextgc, obj2gco(cd)); | ||
61 | setgcref(g->gc.mmudata, obj2gco(cd)); | ||
62 | } else { | ||
63 | setgcref(cd->nextgc, obj2gco(cd)); | ||
64 | setgcref(g->gc.mmudata, obj2gco(cd)); | ||
65 | } | ||
66 | } else if (LJ_LIKELY(!cdataisv(cd))) { | ||
56 | CType *ct = ctype_raw(ctype_ctsG(g), cd->typeid); | 67 | CType *ct = ctype_raw(ctype_ctsG(g), cd->typeid); |
57 | CTSize sz = ctype_hassize(ct->info) ? ct->size : CTSIZE_PTR; | 68 | CTSize sz = ctype_hassize(ct->info) ? ct->size : CTSIZE_PTR; |
58 | lua_assert(ctype_hassize(ct->info) || ctype_isfunc(ct->info) || | 69 | lua_assert(ctype_hassize(ct->info) || ctype_isfunc(ct->info) || |