ref: c6d17c7f00505b3d41f051a0b6c0753e9faf17e9
parent: 40dd4a252f13086148e49bc2763515ceb914b6a8
author: Tor Andersson <tor.andersson@artifex.com>
date: Wed Jan 14 07:01:35 EST 2015
Add finalize callback to userdata objects. When a userdata object is garbage collected, we should invoke a callback to client code to let it know that the associated userdata pointer is no longer in use.
--- a/jsgc.c
+++ b/jsgc.c
@@ -48,6 +48,8 @@
js_regfree(obj->u.r.prog);
if (obj->type == JS_CITERATOR)
jsG_freeiterator(J, obj->u.iter.head);
+ if (obj->type == JS_CUSERDATA && obj->u.user.finalize)
+ obj->u.user.finalize(J, obj->u.user.data);
js_free(J, obj);
}
--- a/jsvalue.c
+++ b/jsvalue.c
@@ -432,7 +432,7 @@
}
}
-void js_newuserdata(js_State *J, const char *tag, void *data)
+void js_newuserdata(js_State *J, const char *tag, void *data, js_Finalize finalize)
{
js_Object *prototype = NULL;
js_Object *obj;
@@ -444,6 +444,7 @@
obj = jsV_newobject(J, JS_CUSERDATA, prototype);
obj->u.user.tag = tag;
obj->u.user.data = data;
+ obj->u.user.finalize = finalize;
js_pushobject(J, obj);
}
--- a/jsvalue.h
+++ b/jsvalue.h
@@ -112,6 +112,7 @@
struct {
const char *tag;
void *data;
+ js_Finalize finalize;
} user;
} u;
js_Object *gcnext;
--- a/mujs.h
+++ b/mujs.h
@@ -29,6 +29,7 @@
typedef void *(*js_Alloc)(void *memctx, void *ptr, unsigned int size);
typedef void (*js_Panic)(js_State *J);
typedef void (*js_CFunction)(js_State *J);
+typedef void (*js_Finalize)(js_State *J, void *p);
/* Basic functions */
js_State *js_newstate(js_Alloc alloc, void *actx);
@@ -125,7 +126,7 @@
void js_newstring(js_State *J, const char *v);
void js_newcfunction(js_State *J, js_CFunction fun, const char *name, unsigned int length);
void js_newcconstructor(js_State *J, js_CFunction fun, js_CFunction con, const char *name, unsigned int length);
-void js_newuserdata(js_State *J, const char *tag, void *data);
+void js_newuserdata(js_State *J, const char *tag, void *data, js_Finalize finalize);
void js_newregexp(js_State *J, const char *pattern, int flags);
void js_pushiterator(js_State *J, int idx, int own);