shithub: libmujs

Download patch

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);