shithub: libmujs

Download patch

ref: fe8cac61e3bf64900e6f608d05e0c4d0f9b4af5e
parent: daa2241087dfbfab3733ff667b762b55df4b9269
author: Tor Andersson <tor.andersson@artifex.com>
date: Tue Oct 19 11:47:16 EDT 2021

Add user data to C functions with extended constructor.

Accessible from C with js_currentfunctiondata(J).

--- a/jsgc.c
+++ b/jsgc.c
@@ -46,6 +46,8 @@
 		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);
+	if (obj->type == JS_CCFUNCTION && obj->u.c.finalize)
+		obj->u.c.finalize(J, obj->u.c.data);
 	js_free(J, obj);
 }
 
--- a/jsrun.c
+++ b/jsrun.c
@@ -176,8 +176,18 @@
 void js_currentfunction(js_State *J)
 {
 	CHECKSTACK(1);
-	STACK[TOP] = STACK[BOT-1];
+	if (BOT > 0)
+		STACK[TOP] = STACK[BOT-1];
+	else
+		STACK[TOP].type = JS_TUNDEFINED;
 	++TOP;
+}
+
+void *js_currentfunctiondata(js_State *J)
+{
+	if (BOT > 0)
+		return STACK[BOT-1].u.object->u.c.data;
+	return NULL;
 }
 
 /* Read values from stack */
--- a/jsvalue.c
+++ b/jsvalue.c
@@ -463,7 +463,7 @@
 	js_pushobject(J, obj);
 }
 
-void js_newcfunction(js_State *J, js_CFunction cfun, const char *name, int length)
+void js_newcfunctionx(js_State *J, js_CFunction cfun, const char *name, int length, void *data, js_Finalize finalize)
 {
 	js_Object *obj = jsV_newobject(J, JS_CCFUNCTION, J->Function_prototype);
 	obj->u.c.name = name;
@@ -470,6 +470,8 @@
 	obj->u.c.function = cfun;
 	obj->u.c.constructor = NULL;
 	obj->u.c.length = length;
+	obj->u.c.data = data;
+	obj->u.c.finalize = finalize;
 	js_pushobject(J, obj);
 	{
 		js_pushnumber(J, length);
@@ -481,6 +483,11 @@
 		}
 		js_defproperty(J, -2, "prototype", JS_DONTENUM | JS_DONTCONF);
 	}
+}
+
+void js_newcfunction(js_State *J, js_CFunction cfun, const char *name, int length)
+{
+	js_newcfunctionx(J, cfun, name, length, NULL, NULL);
 }
 
 /* prototype -- constructor */
--- a/jsvalue.h
+++ b/jsvalue.h
@@ -103,6 +103,8 @@
 			js_CFunction function;
 			js_CFunction constructor;
 			int length;
+			void *data;
+			js_Finalize finalize;
 		} c;
 		js_Regexp r;
 		struct {
--- a/mujs.h
+++ b/mujs.h
@@ -149,6 +149,7 @@
 void js_delindex(js_State *J, int idx, int i);
 
 void js_currentfunction(js_State *J);
+void *js_currentfunctiondata(js_State *J);
 void js_pushglobal(js_State *J);
 void js_pushundefined(js_State *J);
 void js_pushnull(js_State *J);
@@ -165,6 +166,7 @@
 void js_newnumber(js_State *J, double v);
 void js_newstring(js_State *J, const char *v);
 void js_newcfunction(js_State *J, js_CFunction fun, const char *name, int length);
+void js_newcfunctionx(js_State *J, js_CFunction fun, const char *name, int length, void *data, js_Finalize finalize);
 void js_newcconstructor(js_State *J, js_CFunction fun, js_CFunction con, const char *name, int length);
 void js_newuserdata(js_State *J, const char *tag, void *data, js_Finalize finalize);
 void js_newuserdatax(js_State *J, const char *tag, void *data, js_HasProperty has, js_Put put, js_Delete del, js_Finalize finalize);