summaryrefslogtreecommitdiff
path: root/src/alloc.c
diff options
context:
space:
mode:
authorAurélien Aptel <aurelien.aptel@gmail.com>2015-02-11 02:15:14 +0100
committerAurélien Aptel <aurelien.aptel@gmail.com>2015-02-11 02:15:14 +0100
commitc59f2deaae99ca85b0a4fcdd53a3d8ed41d995cd (patch)
tree455db9967d881b610b400ea53c70f87b08eba496 /src/alloc.c
parent9dc8a56a4dc27a752186185743c4fc16c8fced45 (diff)
downloademacs-feature/aptel/dynamic-modules-rc3.tar.gz
add new Lisp_Module type (misc subtype)feature/aptel/dynamic-modules-rc3
Lisp_Module is a new subtype of Misc objects. As other Misc types, it re-uses the marker free list. A module must have a custom destructor, which is automatically called by the GC. Previous module object using the Save_Value type still work and they still have to be free explicitely from Lisp. Their use is now discouraged in modules. A simple module example + tests are available in modules/memtest.
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c58
1 files changed, 55 insertions, 3 deletions
diff --git a/src/alloc.c b/src/alloc.c
index 4daa60ca0f1..5a0b2641b10 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -3657,6 +3657,38 @@ free_marker (Lisp_Object marker)
free_misc (marker);
}
+#ifdef HAVE_LTDL
+/* Create a new module object. */
+Lisp_Object
+module_make_object (module_id_t id, void (*dtor) (void*), void *userptr)
+{
+ Lisp_Object obj;
+ struct Lisp_Module *m;
+
+ eassert (id < MODULE_ID_MAX);
+
+ obj = allocate_misc (Lisp_Misc_Module);
+ m = XMODULE (obj);
+ m->id = id;
+ m->dtor = dtor;
+ m->p = userptr;
+ return obj;
+}
+
+/* Free a module using its own destructor. */
+void
+module_free_object (Lisp_Object obj)
+{
+ /* every change made here probably needs to be done in
+ sweep_marker() */
+
+ struct Lisp_Module *m = XMODULE (obj);
+ m->dtor (m->p);
+
+ free_misc (obj);
+}
+#endif
+
/* Return a newly created vector or string with specified arguments as
elements. If all the arguments are characters that can fit
@@ -6367,6 +6399,12 @@ mark_object (Lisp_Object arg)
mark_overlay (XOVERLAY (obj));
break;
+#ifdef HAVE_LTDL
+ case Lisp_Misc_Module:
+ XMISCANY (obj)->gcmarkbit = 1;
+ break;
+#endif
+
default:
emacs_abort ();
}
@@ -6744,9 +6782,23 @@ sweep_misc (void)
for (i = 0; i < lim; i++)
{
if (!mblk->markers[i].m.u_any.gcmarkbit)
- {
- if (mblk->markers[i].m.u_any.type == Lisp_Misc_Marker)
- unchain_marker (&mblk->markers[i].m.u_marker);
+ {
+ switch (mblk->markers[i].m.u_any.type)
+ {
+ case Lisp_Misc_Marker:
+ unchain_marker (&mblk->markers[i].m.u_marker);
+ break;
+#ifdef HAVE_LTDL
+ case Lisp_Misc_Module:
+ /* Module dtor need to be called */
+ {
+ /* see module_free_object() */
+ struct Lisp_Module *m = &mblk->markers[i].m.u_module;
+ m->dtor (m->p);
+ }
+ break;
+#endif
+ }
/* Set the type of the freed object to Lisp_Misc_Free.
We could leave the type alone, since nobody checks it,
but this might catch bugs faster. */