summaryrefslogtreecommitdiff
path: root/src/lj_cdata.c
diff options
context:
space:
mode:
authorMike Pall <mike>2011-02-28 16:48:13 +0100
committerMike Pall <mike>2011-02-28 16:48:13 +0100
commit83a37aeca74724ef76dee7c8246bdbb88132940d (patch)
tree9dca0cd0aa13cf911ad26c3655533a72bb6790a9 /src/lj_cdata.c
parentcead25f928ac606fc1a13882b818913aab3635a9 (diff)
downloadluajit2-83a37aeca74724ef76dee7c8246bdbb88132940d.tar.gz
FFI: Add ffi.gc() function for finalization of cdata objects.
Diffstat (limited to 'src/lj_cdata.c')
-rw-r--r--src/lj_cdata.c13
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)
/* Free a C data object. */
void LJ_FASTCALL lj_cdata_free(global_State *g, GCcdata *cd)
{
- if (LJ_LIKELY(!cdataisv(cd))) {
+ if (LJ_UNLIKELY(cd->marked & LJ_GC_CDATA_FIN)) {
+ GCobj *root;
+ cd->marked = curwhite(g) | LJ_GC_FINALIZED;
+ if ((root = gcref(g->gc.mmudata)) != NULL) {
+ setgcrefr(cd->nextgc, root->gch.nextgc);
+ setgcref(root->gch.nextgc, obj2gco(cd));
+ setgcref(g->gc.mmudata, obj2gco(cd));
+ } else {
+ setgcref(cd->nextgc, obj2gco(cd));
+ setgcref(g->gc.mmudata, obj2gco(cd));
+ }
+ } else if (LJ_LIKELY(!cdataisv(cd))) {
CType *ct = ctype_raw(ctype_ctsG(g), cd->typeid);
CTSize sz = ctype_hassize(ct->info) ? ct->size : CTSIZE_PTR;
lua_assert(ctype_hassize(ct->info) || ctype_isfunc(ct->info) ||