diff options
author | Aurélien Aptel <aurelien.aptel@gmail.com> | 2015-02-11 02:15:14 +0100 |
---|---|---|
committer | Aurélien Aptel <aurelien.aptel@gmail.com> | 2015-02-11 02:15:14 +0100 |
commit | c59f2deaae99ca85b0a4fcdd53a3d8ed41d995cd (patch) | |
tree | 455db9967d881b610b400ea53c70f87b08eba496 /src/alloc.c | |
parent | 9dc8a56a4dc27a752186185743c4fc16c8fced45 (diff) | |
download | emacs-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.c | 58 |
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. */ |