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